summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:35:26 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:35:26 +0900
commit5ae663c280fa741754b78a4d442c1b5a33e502de (patch)
tree1ed23b28f45a28cd112bffd1a81b713c369b927e
parent8f331da86bcb848ebee6f930317fdb1553c56851 (diff)
downloadglib-5ae663c280fa741754b78a4d442c1b5a33e502de.tar.gz
glib-5ae663c280fa741754b78a4d442c1b5a33e502de.tar.bz2
glib-5ae663c280fa741754b78a4d442c1b5a33e502de.zip
Imported Upstream version 2.69.0upstream/2.69.0
-rw-r--r--.gitlab-ci.yml27
-rw-r--r--.gitlab-ci/android-ndk.Dockerfile3
-rwxr-xr-x.gitlab-ci/meson-junit-report.py2
-rw-r--r--.gitlab-ci/mingw.Dockerfile2
-rwxr-xr-x.gitlab-ci/run-style-check-diff.sh2
-rwxr-xr-x.gitlab-ci/search-common-ancestor.sh8
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--NEWS273
-rw-r--r--README.md13
-rw-r--r--README.win32.md72
-rw-r--r--SECURITY.md67
-rw-r--r--docs/reference/gio/gio-docs.xml4
-rw-r--r--docs/reference/gio/gio-sections-common.txt18
-rw-r--r--docs/reference/gio/gsettings.xml4
-rw-r--r--docs/reference/glib/building.xml48
-rw-r--r--docs/reference/glib/compiling.xml12
-rw-r--r--docs/reference/glib/glib-docs.xml4
-rw-r--r--docs/reference/glib/glib-sections.txt45
-rw-r--r--docs/reference/glib/gvariant-varargs.xml6
-rw-r--r--docs/reference/glib/meson.build2
-rw-r--r--docs/reference/glib/running.xml7
-rw-r--r--docs/reference/gobject/gobject-docs.xml4
-rw-r--r--docs/reference/gobject/gobject-sections.txt3
-rw-r--r--docs/reference/meson.build2
-rw-r--r--fuzzing/README.md2
-rw-r--r--fuzzing/driver.c1
-rw-r--r--fuzzing/fuzz_canonicalize_filename.c19
-rw-r--r--fuzzing/fuzz_paths.c32
-rw-r--r--fuzzing/meson.build4
-rwxr-xr-xgio/data-to-c.py7
-rw-r--r--gio/gapplication.c39
-rw-r--r--gio/gapplicationcommandline.c6
-rw-r--r--gio/gcredentials.h2
-rw-r--r--gio/gdbus-tool.c14
-rw-r--r--gio/gdbusaddress.c6
-rw-r--r--gio/gdbusauth.c3
-rw-r--r--gio/gdbusconnection.c112
-rw-r--r--gio/gdbusintrospection.c14
-rw-r--r--gio/gdbusmessage.c8
-rw-r--r--gio/gdbusnameowning.c2
-rw-r--r--gio/gdbusnamewatching.c2
-rw-r--r--gio/gdbusobjectmanager.c4
-rw-r--r--gio/gdbusobjectmanagerclient.c147
-rw-r--r--gio/gdbusobjectmanagerserver.c7
-rw-r--r--gio/gdbusprivate.c2
-rw-r--r--gio/gdbusprivate.h2
-rw-r--r--gio/gdbusproxy.c21
-rw-r--r--gio/gdbusserver.c14
-rw-r--r--gio/gdbusutils.c38
-rw-r--r--gio/gdbusutils.h2
-rw-r--r--gio/gdesktopappinfo.c2
-rw-r--r--gio/gdtlsconnection.c98
-rw-r--r--gio/gdtlsconnection.h11
-rw-r--r--gio/gemblemedicon.c2
-rw-r--r--gio/gfdonotificationbackend.c4
-rw-r--r--gio/gfileenumerator.c5
-rw-r--r--gio/gfileinfo.c165
-rw-r--r--gio/gfileinfo.h10
-rw-r--r--gio/ginputstream.c12
-rw-r--r--gio/gio-tool-cat.c2
-rw-r--r--gio/gio-tool-copy.c2
-rw-r--r--gio/gio-tool-info.c2
-rw-r--r--gio/gio-tool-launch.c2
-rw-r--r--gio/gio-tool-list.c2
-rw-r--r--gio/gio-tool-mime.c2
-rw-r--r--gio/gio-tool-mkdir.c2
-rw-r--r--gio/gio-tool-monitor.c2
-rw-r--r--gio/gio-tool-mount.c2
-rw-r--r--gio/gio-tool-move.c2
-rw-r--r--gio/gio-tool-open.c2
-rw-r--r--gio/gio-tool-remove.c2
-rw-r--r--gio/gio-tool-rename.c2
-rw-r--r--gio/gio-tool-save.c2
-rw-r--r--gio/gio-tool-set.c2
-rw-r--r--gio/gio-tool-trash.c2
-rw-r--r--gio/gio-tool-tree.c2
-rw-r--r--gio/gioenums.h45
-rw-r--r--gio/giomodule.c6
-rw-r--r--gio/gkeyfilesettingsbackend.c8
-rw-r--r--gio/glib-compile-resources.c2
-rw-r--r--gio/glib-compile-schemas.c2
-rw-r--r--gio/glocalfile.c5
-rw-r--r--gio/gnotification.c23
-rw-r--r--gio/gpollableinputstream.c6
-rw-r--r--gio/gresource-tool.c9
-rw-r--r--gio/gseekable.c3
-rw-r--r--gio/gsettings-tool.c15
-rw-r--r--gio/gsettings.c24
-rw-r--r--gio/gsettingsschema-internal.h3
-rw-r--r--gio/gsettingsschema.c18
-rw-r--r--gio/gsocket.c8
-rw-r--r--gio/gsocketcontrolmessage.c2
-rw-r--r--gio/gsocketlistener.c2
-rw-r--r--gio/gsubprocess.c10
-rw-r--r--gio/gtask.c6
-rw-r--r--gio/gtestdbus.c2
-rw-r--r--gio/gtlscertificate.c308
-rw-r--r--gio/gtlscertificate.h18
-rw-r--r--gio/gtlsconnection.c142
-rw-r--r--gio/gtlsconnection.h24
-rw-r--r--gio/gtlspassword.c6
-rw-r--r--gio/gunixmounts.c9
-rw-r--r--gio/gunixsocketaddress.c3
-rw-r--r--gio/gwin32appinfo.c7
-rw-r--r--gio/gwin32mount.c187
-rwxr-xr-xgio/gwin32packageparser.c2
-rw-r--r--gio/gwin32registrykey.c15
-rw-r--r--gio/tests/actions.c34
-rw-r--r--gio/tests/appinfo.c3
-rw-r--r--gio/tests/async-close-output-stream.c8
-rw-r--r--gio/tests/basic-application.c8
-rw-r--r--gio/tests/buffered-input-stream.c3
-rw-r--r--gio/tests/contenttype.c6
-rw-r--r--gio/tests/contexts.c7
-rw-r--r--gio/tests/converter-stream.c20
-rw-r--r--gio/tests/dbus-appinfo.c8
-rw-r--r--gio/tests/echo-server.c2
-rw-r--r--gio/tests/fake-service-name.c3
-rw-r--r--gio/tests/file.c5
-rw-r--r--gio/tests/filter-cat.c2
-rw-r--r--gio/tests/filter-streams.c3
-rw-r--r--gio/tests/g-file-info-filesystem-readonly.c3
-rw-r--r--gio/tests/g-file-info.c149
-rw-r--r--gio/tests/g-file.c108
-rw-r--r--gio/tests/gapplication-example-cmdline3.c2
-rw-r--r--gio/tests/gapplication-example-cmdline4.c2
-rw-r--r--gio/tests/gapplication.c76
-rw-r--r--gio/tests/gdbus-connection-slow.c6
-rw-r--r--gio/tests/gdbus-connection.c3
-rw-r--r--gio/tests/gdbus-daemon.c2
-rw-r--r--gio/tests/gdbus-example-export.c3
-rw-r--r--gio/tests/gdbus-example-own-name.c2
-rwxr-xr-xgio/tests/gdbus-example-peer.c3
-rw-r--r--gio/tests/gdbus-example-server.c3
-rw-r--r--gio/tests/gdbus-example-subtree.c12
-rw-r--r--gio/tests/gdbus-example-watch-name.c2
-rw-r--r--gio/tests/gdbus-example-watch-proxy.c2
-rw-r--r--gio/tests/gdbus-exit-on-close.c2
-rw-r--r--gio/tests/gdbus-export.c16
-rw-r--r--gio/tests/gdbus-names.c335
-rw-r--r--gio/tests/gdbus-non-socket.c3
-rw-r--r--gio/tests/gdbus-peer-object-manager.c1
-rw-r--r--gio/tests/gdbus-peer.c6
-rw-r--r--gio/tests/gdbus-proxy.c2
-rw-r--r--gio/tests/gdbus-serialization.c5
-rw-r--r--gio/tests/gdbus-test-codegen.c4
-rw-r--r--gio/tests/gdbus-testserver.c5
-rw-r--r--gio/tests/glistmodel.c5
-rw-r--r--gio/tests/gnotification-server.c2
-rw-r--r--gio/tests/gsettings.c13
-rw-r--r--gio/tests/gsubprocess-testprog.c2
-rw-r--r--gio/tests/gsubprocess.c17
-rw-r--r--gio/tests/gtesttlsbackend.c42
-rw-r--r--gio/tests/gtesttlsbackend.h3
-rw-r--r--gio/tests/httpd.c2
-rw-r--r--gio/tests/live-g-file.c2
-rw-r--r--gio/tests/memory-output-stream.c11
-rw-r--r--gio/tests/meson.build8
-rw-r--r--gio/tests/mimeapps.c2
-rw-r--r--gio/tests/network-address.c13
-rw-r--r--gio/tests/network-monitor-race.c3
-rw-r--r--gio/tests/org.gtk.schemasourcecheck.gschema.xml3
-rw-r--r--gio/tests/proxy-test.c4
-rw-r--r--gio/tests/readwrite.c6
-rw-r--r--gio/tests/resolver.c2
-rw-r--r--gio/tests/send-data.c2
-rw-r--r--gio/tests/sleepy-stream.c1
-rw-r--r--gio/tests/socket-client.c2
-rw-r--r--gio/tests/socket-common.c2
-rw-r--r--gio/tests/socket-listener.c2
-rw-r--r--gio/tests/socket-server.c2
-rw-r--r--gio/tests/socket-service.c4
-rw-r--r--gio/tests/socket.c20
-rw-r--r--gio/tests/testfilemonitor.c11
-rw-r--r--gio/tests/tls-certificate.c210
-rw-r--r--gio/tests/trash.c6
-rw-r--r--gio/tests/unix-streams.c36
-rw-r--r--glib.doap2
-rw-r--r--glib.supp2
-rw-r--r--glib/deprecated/gthread.h4
-rw-r--r--glib/dirent/dirent.c2
-rw-r--r--glib/dirent/dirent.h4
-rw-r--r--glib/galloca.h11
-rw-r--r--glib/garray.c33
-rw-r--r--glib/gasyncqueue.c2
-rw-r--r--glib/gatomic.h22
-rw-r--r--glib/gbitlock.c101
-rw-r--r--glib/gbookmarkfile.c99
-rw-r--r--glib/gbytes.c72
-rw-r--r--glib/gbytes.h7
-rw-r--r--glib/gcharset.c87
-rw-r--r--glib/gcharsetprivate.h4
-rw-r--r--glib/gconvert.c47
-rw-r--r--glib/gconvertprivate.h40
-rw-r--r--glib/gdate.c42
-rw-r--r--glib/gdatetime.c23
-rw-r--r--glib/gdir.c4
-rw-r--r--glib/gerror.c30
-rw-r--r--glib/gerror.h5
-rw-r--r--glib/gfileutils.c12
-rw-r--r--glib/ghash.c2
-rw-r--r--glib/glib-typeof.h43
-rw-r--r--glib/glib.h1
-rw-r--r--glib/gmacros.h230
-rw-r--r--glib/gmain.c29
-rw-r--r--glib/gmain.h27
-rw-r--r--glib/gmem.h10
-rw-r--r--glib/goption.c17
-rw-r--r--glib/goption.h18
-rw-r--r--glib/gpattern.c110
-rw-r--r--glib/gpattern.h14
-rw-r--r--glib/grcbox.h8
-rw-r--r--glib/grefcount.c33
-rw-r--r--glib/gregex.c34
-rw-r--r--glib/gscanner.c2
-rw-r--r--glib/gspawn-win32.c67
-rw-r--r--glib/gspawn.c128
-rw-r--r--glib/gspawn.h14
-rw-r--r--glib/gstring.c20
-rw-r--r--glib/gstrvbuilder.c44
-rw-r--r--glib/gstrvbuilder.h11
-rw-r--r--glib/gtester.c1
-rw-r--r--glib/gtestutils.c15
-rw-r--r--glib/gthreadpool.c34
-rw-r--r--glib/gthreadpool.h7
-rw-r--r--glib/gtree.c11
-rw-r--r--glib/gtree.h4
-rw-r--r--glib/gunicollate.c2
-rw-r--r--glib/guri.c4
-rw-r--r--glib/gutf8.c26
-rw-r--r--glib/gutils.c134
-rw-r--r--glib/guuid.c2
-rw-r--r--glib/gvariant-core.c154
-rw-r--r--glib/gvariant-serialiser.c112
-rw-r--r--glib/gvariant-serialiser.h4
-rw-r--r--glib/gvariant.c60
-rw-r--r--glib/gvarianttypeinfo.c4
-rw-r--r--glib/gvarianttypeinfo.h8
-rw-r--r--glib/gversionmacros.h44
-rw-r--r--glib/gwin32-private.c30
-rw-r--r--glib/gwin32.c275
-rw-r--r--glib/meson.build18
-rw-r--r--glib/pcre/COPYING5
-rw-r--r--glib/pcre/meson.build50
-rw-r--r--glib/pcre/pcre.h507
-rw-r--r--glib/pcre/pcre_byte_order.c286
-rw-r--r--glib/pcre/pcre_chartables.c196
-rw-r--r--glib/pcre/pcre_compile.c8213
-rw-r--r--glib/pcre/pcre_config.c168
-rw-r--r--glib/pcre/pcre_dfa_exec.c3611
-rw-r--r--glib/pcre/pcre_exec.c7144
-rw-r--r--glib/pcre/pcre_fullinfo.c204
-rw-r--r--glib/pcre/pcre_get.c585
-rw-r--r--glib/pcre/pcre_globals.c88
-rw-r--r--glib/pcre/pcre_internal.h2334
-rw-r--r--glib/pcre/pcre_jit_compile.c7497
-rw-r--r--glib/pcre/pcre_newline.c182
-rw-r--r--glib/pcre/pcre_ord2utf8.c95
-rw-r--r--glib/pcre/pcre_string_utils.c166
-rw-r--r--glib/pcre/pcre_study.c1532
-rw-r--r--glib/pcre/pcre_tables.c600
-rw-r--r--glib/pcre/pcre_valid_utf8.c297
-rw-r--r--glib/pcre/pcre_version.c93
-rw-r--r--glib/pcre/pcre_xclass.c196
-rw-r--r--glib/pcre/ucp.h179
-rw-r--r--glib/tests/642026.c3
-rw-r--r--glib/tests/array-test.c2
-rw-r--r--glib/tests/atomic.c7
-rw-r--r--glib/tests/base64.c3
-rw-r--r--glib/tests/bookmarkfile.c22
-rw-r--r--glib/tests/bytes.c142
-rw-r--r--glib/tests/charset.c2
-rw-r--r--glib/tests/cond.c3
-rw-r--r--glib/tests/date.c5
-rw-r--r--glib/tests/error.c22
-rw-r--r--glib/tests/fileutils.c4
-rw-r--r--glib/tests/gdatetime.c122
-rw-r--r--glib/tests/gutils-user-database.c1
-rw-r--r--glib/tests/guuid.c1
-rw-r--r--glib/tests/gvariant.c43
-rw-r--r--glib/tests/hash.c10
-rw-r--r--glib/tests/keyfile.c18
-rw-r--r--glib/tests/logging.c3
-rw-r--r--glib/tests/mainloop.c37
-rw-r--r--glib/tests/mem-overflow.c4
-rw-r--r--glib/tests/once.c2
-rw-r--r--glib/tests/option-argv0.c2
-rw-r--r--glib/tests/option-context.c154
-rw-r--r--glib/tests/pattern.c35
-rw-r--r--glib/tests/rand.c3
-rw-r--r--glib/tests/regex.c15
-rw-r--r--glib/tests/spawn-path-search-helper.c2
-rw-r--r--glib/tests/spawn-singlethread.c10
-rw-r--r--glib/tests/string.c82
-rw-r--r--glib/tests/strvbuilder.c37
-rw-r--r--glib/tests/test-printf.c8
-rw-r--r--glib/tests/testing.c50
-rw-r--r--glib/tests/thread-pool.c56
-rw-r--r--glib/tests/tree.c31
-rw-r--r--glib/tests/uri.c2
-rw-r--r--glib/tests/utf8-validate.c2
-rw-r--r--glib/tests/utils.c29
-rw-r--r--glib/tests/win32.c62
-rw-r--r--glib/update-pcre/digitab.patch94
-rw-r--r--glib/update-pcre/memory.patch40
-rw-r--r--glib/update-pcre/ucp.patch834
-rw-r--r--glib/update-pcre/update.sh124
-rw-r--r--gmodule/gmodule-dl.c54
-rw-r--r--gobject/gboxed.c1
-rw-r--r--gobject/glib-types.h11
-rw-r--r--gobject/gobject.c61
-rw-r--r--gobject/gobject.h9
-rw-r--r--gobject/gsignal.h7
-rw-r--r--gobject/gtype.c3
-rw-r--r--gobject/gtype.h2
-rw-r--r--gobject/gvaluetypes.c2
-rw-r--r--gobject/tests/binding.c7
-rw-r--r--gobject/tests/boxed.c24
-rw-r--r--gobject/tests/ifaceproperties.c3
-rw-r--r--gobject/tests/object.c3
-rw-r--r--gobject/tests/properties.c4
-rw-r--r--gobject/tests/reference.c14
-rw-r--r--meson.build97
-rw-r--r--meson_options.txt5
-rw-r--r--msvc_recommended_pragmas.h4
-rw-r--r--po/he.po1788
-rw-r--r--po/oc.po858
-rw-r--r--po/sr.po66
-rw-r--r--po/zh_CN.po157
-rw-r--r--po/zh_TW.po1318
-rw-r--r--subprojects/gtk-doc.wrap2
-rw-r--r--subprojects/libpcre.wrap11
-rw-r--r--tests/dirname-test.c5
-rw-r--r--tests/gio-test.c7
-rw-r--r--tests/gobject/defaultiface.c7
-rw-r--r--tests/gobject/performance-threaded.c13
-rw-r--r--tests/gobject/performance.c9
-rw-r--r--tests/gobject/references.c3
-rw-r--r--tests/gobject/testcommon.h9
-rw-r--r--tests/gobject/testgobject.c13
-rw-r--r--tests/gobject/timeloop-closure.c4
-rw-r--r--tests/mainloop-test.c4
-rw-r--r--tests/memchunks.c4
-rw-r--r--tests/onceinit.c2
-rw-r--r--tests/refcount/objects.c2
-rw-r--r--tests/slice-threadinit.c4
-rw-r--r--tests/testgdate.c4
-rw-r--r--tests/testglib.c12
-rw-r--r--tests/thread-test.c2
-rw-r--r--tests/threadpool-test.c8
-rw-r--r--tests/timeloop.c4
-rw-r--r--tests/unicode-collate.c2
-rw-r--r--tests/unicode-encoding.c10
353 files changed, 7551 insertions, 39620 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 05e473138..73fbc1ba6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,11 +10,11 @@ cache:
- _ccache/
variables:
- FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/glib/fedora:v10"
+ FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/glib/fedora:v11"
COVERITY_IMAGE: "registry.gitlab.gnome.org/gnome/glib/coverity:v1"
- DEBIAN_IMAGE: "registry.gitlab.gnome.org/gnome/glib/debian-stable:v7"
- ANDROID_IMAGE: "registry.gitlab.gnome.org/gnome/glib/android-ndk:v3"
- MINGW_IMAGE: "registry.gitlab.gnome.org/gnome/glib/mingw:v2"
+ DEBIAN_IMAGE: "registry.gitlab.gnome.org/gnome/glib/debian-stable:v8"
+ ANDROID_IMAGE: "registry.gitlab.gnome.org/gnome/glib/android-ndk:v4"
+ MINGW_IMAGE: "registry.gitlab.gnome.org/gnome/glib/mingw:v3"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
G_MESSAGES_DEBUG: all
MESON_COMMON_OPTIONS_NO_WARNING: "--buildtype debug --wrap-mode=nodownload"
@@ -170,7 +170,7 @@ installed-tests:
# FIXME install newer gobject-introspection
# with GMemoryMonitor support, see:
# https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/193
- - git clone --branch master --depth 1 --no-tags https://gitlab.gnome.org/GNOME/gobject-introspection.git
+ - git clone --single-branch --depth 1 --no-tags https://gitlab.gnome.org/GNOME/gobject-introspection.git
- cd gobject-introspection
- /usr/bin/meson _build --prefix=/usr --libdir=/usr/lib64
- ninja -C _build
@@ -270,7 +270,10 @@ cross-android_api21_arm64:
# FIXME: add --werror
# We use -Diconv=auto to test that we successfully detect that iconv is not
# provided by android api 21, and detect the external iconv instead.
- - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_21.txt -Diconv=auto -Dinternal_pcre=true _build
+ # FIXME: Work around a bug in Meson 0.49 where --wrap-mode=nodownload also
+ # disables fallback subprojects, by passing --wrap-mode=default. Fixed in
+ # Meson commit 47b9c1a564756ac48a55da9a7c4d91787399c645
+ - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_21.txt -Diconv=auto --wrap-mode=default _build
- ninja -C _build
cross-android_api28_arm64:
@@ -278,7 +281,10 @@ cross-android_api28_arm64:
image: $ANDROID_IMAGE
script:
# FIXME: add --werror
- - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_28.txt -Dinternal_pcre=true _build
+ # FIXME: Work around a bug in Meson 0.49 where --wrap-mode=nodownload also
+ # disables fallback subprojects, by passing --wrap-mode=default. Fixed in
+ # Meson commit 47b9c1a564756ac48a55da9a7c4d91787399c645
+ - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_28.txt --wrap-mode=default _build
- ninja -C _build
cross-mingw64:
@@ -286,7 +292,10 @@ cross-mingw64:
image: $MINGW_IMAGE
script:
# FIXME: Add --werror
- - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_mingw64.txt _build
+ # FIXME: Work around a bug in Meson 0.49 where --wrap-mode=nodownload also
+ # disables fallback subprojects, by passing --wrap-mode=default. Fixed in
+ # Meson commit 47b9c1a564756ac48a55da9a7c4d91787399c645
+ - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_mingw64.txt --wrap-mode=default _build
- ninja -C _build
msys2-mingw32:
@@ -513,7 +522,7 @@ coverity:
pages:
stage: deploy
only:
- - master
+ - main
needs: ['coverage', 'style-check-diff']
script:
- mv _coverage/ public/
diff --git a/.gitlab-ci/android-ndk.Dockerfile b/.gitlab-ci/android-ndk.Dockerfile
index 56b186cbb..90b95826d 100644
--- a/.gitlab-ci/android-ndk.Dockerfile
+++ b/.gitlab-ci/android-ndk.Dockerfile
@@ -1,4 +1,4 @@
-FROM fedora:28
+FROM fedora:31
RUN dnf -y install \
autoconf \
@@ -44,6 +44,7 @@ RUN dnf -y install \
ncurses-compat-libs \
ninja-build \
pcre-devel \
+ python-unversioned-command \
python3 \
python3-pip \
python3-wheel \
diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py
index 1855b4907..1d57ead50 100755
--- a/.gitlab-ci/meson-junit-report.py
+++ b/.gitlab-ci/meson-junit-report.py
@@ -27,7 +27,7 @@ aparser.add_argument(
"--branch",
metavar="NAME",
help="Branch of the project being tested",
- default="master",
+ default="main",
)
aparser.add_argument(
"--output",
diff --git a/.gitlab-ci/mingw.Dockerfile b/.gitlab-ci/mingw.Dockerfile
index d89de8cfb..2928b562c 100644
--- a/.gitlab-ci/mingw.Dockerfile
+++ b/.gitlab-ci/mingw.Dockerfile
@@ -1,4 +1,4 @@
-FROM fedora:29
+FROM fedora:31
RUN dnf -y install \
bindfs \
diff --git a/.gitlab-ci/run-style-check-diff.sh b/.gitlab-ci/run-style-check-diff.sh
index a04bd0731..929cf28a4 100755
--- a/.gitlab-ci/run-style-check-diff.sh
+++ b/.gitlab-ci/run-style-check-diff.sh
@@ -25,7 +25,7 @@ exit_status=$?
# style with the changes they’re making.)
echo ""
echo "Note that clang-format output is advisory and cannot always match the GLib coding style, documented at"
-echo " https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
+echo " https://gitlab.gnome.org/GNOME/gtk/blob/HEAD/docs/CODING-STYLE.md"
echo "Warnings from this tool can be ignored in favour of the documented coding style,"
echo "or in favour of matching the style of existing surrounding code."
diff --git a/.gitlab-ci/search-common-ancestor.sh b/.gitlab-ci/search-common-ancestor.sh
index a7a3ac44c..96f45fe69 100755
--- a/.gitlab-ci/search-common-ancestor.sh
+++ b/.gitlab-ci/search-common-ancestor.sh
@@ -9,7 +9,7 @@ ancestor_horizon=28 # days (4 weeks)
# branches.
#
# Limit the fetch to a certain date horizon to limit the amount of data we get.
-# If the branch was forked from origin/master before this horizon, it should
+# If the branch was forked from origin/main before this horizon, it should
# probably be rebased.
if ! git ls-remote --exit-code upstream >/dev/null 2>&1 ; then
git remote add upstream https://gitlab.gnome.org/GNOME/glib.git
@@ -18,7 +18,7 @@ git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%
# Work out the newest common ancestor between the detached HEAD that this CI job
# has checked out, and the upstream target branch (which will typically be
-# `upstream/master` or `upstream/glib-2-62`).
+# `upstream/main` or `upstream/glib-2-62`).
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` or `${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}`
# are only defined if we’re running in a merge request pipeline,
# fall back to `${CI_DEFAULT_BRANCH}` or `${CI_COMMIT_BRANCH}` respectively
@@ -29,8 +29,8 @@ git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent "origin/${source_branch}") | head -1)
if [ -z "${newest_common_ancestor_sha}" ]; then
- echo "Couldn’t find common ancestor with upstream master. This typically"
- echo "happens if you branched from master a long time ago. Please update"
+ echo "Couldn’t find common ancestor with upstream main branch. This typically"
+ echo "happens if you branched from main a long time ago. Please update"
echo "your clone, rebase, and re-push your branch."
exit 1
fi
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 52f17b1d9..ba8039d4c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -256,7 +256,7 @@ to avoid unnecessary breakage, and to take advantage of the knowledge about GLib
that has been built up over the years, we’d like to ask people contributing to
GLib to follow a few rules:
-0. Never push to the `master` branch, or any stable branches, directly; you
+0. Never push to the `main` branch, or any stable branches, directly; you
should always go through a merge request, to ensure that the code is
tested on the CI infrastructure at the very least. A merge request is
also the proper place to get a comprehensive code review from the core
diff --git a/NEWS b/NEWS
index b9f3414f0..c3a56b9bf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,68 +1,255 @@
-Overview of changes in GLib 2.68.4
+Overview of changes in GLib 2.69.0
==================================
-* Bugs fixed:
- - #2454 Read past the end of buffer in g_win32_package_parser_enum_packages
- - !2158 Backport !2155 “glocalfilemonitor: Avoid a deadlock on finalization” to glib-2-68
- - !2175 Backport !2174 “data-to-c.py: generate new-line at the end of the file” to glib-2-68
- - !2183 Backport !2180 “correctly use 3 parameters for close_range” to glib-2-68
- - !2186 Backport !2185 “glocalfile: Fix the global trash dir detection” to glib-2-68
- - !2209 Backport !2208 “g_string_replace: Don't replace empty string more than once per location” to glib-2-68
- - !2220 Backport GWin32AppInfo fixes to glib-2-68
+* Fix a crash in `GKeyFile` when parsing a file which contains translations
+ using a `GKeyFile` instance which has loaded another file previously (#2361)
-* Translation updates:
- - Chinese (China)
- - Chinese (Taiwan)
- - Occitan (post 1500)
+* Pin GIO DLL in memory on Windows (!2016)
+* Fix building third-party projects against GLib on CentOS 7 (work by
+ Ignacio Casal Quinteiro) (#2387)
-Overview of changes in GLib 2.68.3
-==================================
+* Add `g_thread_pool_new_full()` API to allow queued `GThreadPool` data to be
+ freed if the pool is freed early (work by Nitin Wartkar) (#121)
-* Bugs fixed:
- - #2311 testfilemonitor test leaks ip_watched_file_t struct
- - #2417 GFile: `g_file_replace_contents()` reports `G_IO_ERROR_WRONG_ETAG` when saving from a symlink
- - !2133 Backport !2128 “inotify: Fix a memory leak” to glib-2-68
- - !2137 Backport !2136 “tlscertificate: Avoid possible invalid read” to glib-2-68
- - !2141 Backport !2138 “glocalfileoutputstream: Fix ETag check when replacing through a symlink” to glib-2-68
+* Ensure `dlerror()` is used with locking as it’s not thread-safe in some libc
+ implementations (#399)
+* Add `g_dbus_is_error_name()` and `g_dbus_is_interface_name()` convenience
+ functions (work by Nitin Wartkar) (#402)
-Overview of changes in GLib 2.68.2
-==================================
+* Drop internal libpcre copy in favour of a subproject from wrapdb (#962, #642)
-* Fix building third-party projects against GLib on CentOS 7 (work by
- Ignacio Casal Quinteiro) (#2387)
+* Add `g_prefix_error_literal()` helper function (work by Emmanuel Fleury,
+ building on work by Dan Williams) (#663)
-* Bugs fixed:
- - #2387 json-glib does not build with glib 2.68.1
- - !2060 gmacros: check that __cplusplus or _MSC_VER is defined
- - !2068 gmacros: missing check if __STDC_VERSION__ is defined
- - !2079 Backport !2078 “gthreadedresolver: don't ignore flags in lookup_by_name_with_flags” to glib-2-68
+* Add `g_bytes_get_region()` to get data from a `GBytes` with range checks
+ (work by Nitin Wartkar, building on work by Allison Karlitskaya) (#1098)
-* Translation updates:
- - Nepali
- - Serbian
+* Add `g_object_take_ref()` to sink a floating ref (work by Nitin Wartkar,
+ building on work by Allison Karlitskaya) (#1112)
+* Optimise grefcount atomic operations (work by Nishal Kulkarni) (#1583)
-Overview of changes in GLib 2.68.1
-==================================
+* Fix resolving child GSettings schemas from the parent’s schema source (work
+ by Christian Persch) (#1884)
-* Fix a crash in `GKeyFile` when parsing a file which contains translations
- using a `GKeyFile` instance which has loaded another file previously (#2361)
+* Fix `g_date_time_format()` return value encoding if `LC_TIME` is not a UTF-8
+ locale but other locale settings are (work by Frederic Martinsons) (#2055)
-* Pin GIO DLL in memory on Windows (!2016)
+* Set app name in freedesktop.org notifications with `GNotification` (work
+ by André Apitzsch) (#2069)
+
+* Significantly improve retrieval of mount data on Windows (work by LRN based
+ on initial analysis by Jehan Pagès) (#2096)
+
+* Add `g_file_info_get_(access|creation)_date_time()` accessors (work
+ by Abanoub Ghadban) (#2281)
+
+* Always apply the remove_dot_segments algorithm to URIs in `g_uri_parse()`;
+ previously it was only applied to relative URIs (work
+ by Carlos Garcia Campos) (#2342)
+
+* Rename git `master` branch to `main` (#2348)
+
+* Various macro and version check cleanup (work by Gaël Bonithon,
+ Robin Verdenal-Tallieux, Nishal Kulkarni) (#2376, #2388, #2389)
+
+* Add a `GTlsConnectionClass.get_negotiated_protocol` vfunc so that
+ `g_tls_connection_get_negotiated_protocol()` can be made thread-safe
+ (work by Michael Catanzaro) (#2393)
+
+* Improve guess about whether a Windows process is a console process
+ (work by Princeton Ferro with input from LRN) (!1662)
+
+* Add `g_steal_fd()` function (work by Simon McVittie) (!1966)
+
+* Add `g_spawn_check_wait_status()` and distinguish more carefully between
+ wait status and exit status in the `GSpawn` API (work by Simon McVittie) (!1967)
+
+* Document GLib’s security policy; see
+ https://gitlab.gnome.org/GNOME/glib/-/blob/main/SECURITY.md (!1985)
+
+* Add `g_tree_remove_all()` (work by Lighto-Ku) (!1986)
+
+* Simplify exception handling on Windows to eliminate risk of it failing due
+ to prior heap corruption (work by LRN) (!2031)
+
+* Fix handling EOF when reading from SOCKS5 proxy stream (work
+ by Benjamin Berg) (!2032)
+
+* Unset the registered state of a `GApplication` after it has shut down (work
+ by Marco Trevisan) (!2056)
+
+* Support `GPattern` as a boxed type (work by Marco Trevisan) (!2066)
+
+* Add `g_tls_connection_get_protocol_version()` and
+ `g_tls_connection_get_ciphersuite_name()` to get TLS connection information
+ (work by Michael Catanzaro) (!2077)
+
+* Make TLS private key properties readable in `GTlsCertificate` (work
+ by Michael Catanzaro) (!2087)
+
+* Fix detection of static libintl when building on macOS (work
+ by Jonas Hahnfeld) (!2109)
+
+* Add `g_strv_builder_addv()` and `g_strv_builder_add_many()` to the
+ `GStrvBuilder` API (work by Alexandros Theodotou) (!2112)
+
+* Add `not-valid-before`, `not-valid-after`, `subject-name`, `issuer-name`,
+ `dns-names`, `ip-addresses` properties to `GTlsCertificate`
+ (work by Ross Wollman) (!2113, !2142)
+
+* Add PKCS#11 flags to `GTlsPasswordFlags` (work by Patrick Griffis) (!2126)
* Bugs fixed:
+ - #121 GThreadPool and the ability to free data waiting to be handled
+ - #229 g_match_info_fetch_named not return empty string as expected
+ - #310 ref doc doesn't talk about "helper getters" optimization in g_file_info.c
+ - #399 dlerror() not thread-safe in all libc, making gmodule-dl.c's fetch_dlerror fail sometimes
+ - #402 please consider: #define g_dbus_is_error_name(x) g_dbus_is_interface_name (x)
+ - #626 Add documentation example for GArray and g_array_set_clear_func()
+ - #642 update to pcre 8.35+
+ - #663 [patch] add g_prefix_error_literal()
+ - #793 Potentially confusing error message when object doesn't exist
+ - #817 gobject: Allow passing %NULL for @data in g_object_remove_toggle_ref
+ - #962 drop embedded pcre copy
+ - #1036 gdbusproxy stops tracking if dbus service restarts
+ - #1098 GBytes: add range-checked pointer getter
+ - #1112 GObject: add g_object_take_ref()
+ - #1583 Optimise gatomicrefcount operations
+ - #1864 Somewhat misleading documentation of GSourceFuncs
+ - #1884 `g_settings_get_child` not compatible with `g_settings_schema_source_new_from_directory`
+ - #2011 Add additional unit tests for D-Bus name watching
+ - #2055 g_date_time_format() does not return UTF-8 if LC_TIME is not UTF8 but other locale settings are UTF-8
+ - #2069 FreedesktopNotification fails to set app_name
+ - #2096 SHGetFileInfoW() is not reliable (time-wise)
+ - #2281 Add g_file_info_get_(access|creation)_date_time()
+ - #2300 Crash on Windows MSVC build around gio
+ - #2311 testfilemonitor test leaks ip_watched_file_t struct
+ - #2340 GIO tests fail to build with clang-cl
+ - #2342 g_uri_parse doesn't apply the remove_dot_segments algorithm to the path
+ - #2348 Investigate renaming master git branch to main
+ - #2352 RUN_FIRST | RUN_CLEANUP signals with a default handler ignore return values from user handlers
+ - #2359 GLib 2.68.0: gio-querymodules segfaults on Windows
- #2361 g_key_file_load_from_file segfaults on "Key[*]="like lines
- - !1997 Backport !1996 “Include glibconfig.h to get the G_OS_UNIX token” to glib-2-68
+ - #2363 g_newa() doesn’t check for multiplication overflow
+ - #2368 g_task_run_in_thread () limits are not clear
+ - #2369 glocalfile: Add native exfat magic number to filesystem list
+ - #2376 GLIB_VERSION_MAX_ALLOWED < 2.60 does not warn when using G_GNUC_FALLTHROUGH
+ - #2387 json-glib does not build with glib 2.68.1
+ - #2388 Pixman compilation error due to glib
+ - #2389 Use G_GNUC_CHECK_VERSION to check the GNUC version
+ - #2393 g_tls_connection_get_negotiated_protocol() is not threadsafe
+ - #2397 Slow to list device in windows
+ - #2399 Change spelling of ‘serialise’ to ‘serialize’ in documentation
+ - #2405 Mention that GNotification requires an installed .desktop file to work
+ - #2409 Project crashes when executing g_application_mark_busy
+ - #2414 Devhelp: Glib Reference Manual/Glib Overview/Running Glib Applications formatting issue.
+ - #2416 certificate: g_tls_certificate_new_from_pem invalid read on non null terminated data
+ - #2417 GFile: `g_file_replace_contents()` reports `G_IO_ERROR_WRONG_ETAG` when saving from a symlink
+ - #2418 gatomic: __atomic functions are called for CV-qualified output variables
+ - #2423 resources.c:656:test_resource_binary_linked: 'found' should be TRUE
+ - !1514 gbookmarkfile: Don't crash if we're not visited
+ - !1662 gspawn-win32: improve guess whether process is console process
+ - !1812 docs: Expand documentation about D-Bus GUIDs
+ - !1957 Fix more warnings
+ - !1965 gversionmacros: Add version macros for GLib 2.70
+ - !1966 Add g_steal_fd() to API
+ - !1967 Distinguish more clearly between wait status and exit status
+ - !1969 glib_typeof: Move definition to its own header
+ - !1985 docs: Add a policy for handling security issues
+ - !1986 make g_tree_remove_all public
+ - !1996 Include glibconfig.h to get the G_OS_UNIX token
+ - !1998 gpollableinputstream: Add missing annotation
+ - !1999 goption.c: Simplfy parse_short_option()
+ - !2004 Some improvements to clang-cl builds
+ - !2005 introspection: Remove 'caller-allocates' from POD types
+ - !2006 fuzzing: Add fuzz tests for functions which parse paths
+ - !2008 tests: Deactivate tls-bindings test suite for windows
+ - !2011 docs: Fix example program link
+ - !2012 docs: Replace git.gnome.org with gitlab.gnome.org urls
+ - !2013 fuzzing: Fix assertion failure in fuzz_paths.c
- !2016 GIO W32: Pin gio DLL
- - !2021 Backport MR !2016 (GIO W32: Pin gio DLL) into glib-2-68
- - !2022 Few fixes and notes for building on Visual Studio 2012 and earlier
- - !2034 Backport MR !2032 (gkeyfile: Drop a redundant check) into glib-2-68
- - !2035 Backport !2026 “Split g_test_log() messages that contain multiple lines” to glib-2-68
+ - !2023 gtlspassword: Fix g-i annotation of return for g_tls_password_get_value
+ - !2025 [th/gdbus-cleanup] two minor cleanup patches for gdbusconnection.c
+ - !2026 Split g_test_log() messages that contain multiple lines
+ - !2027 Fix a handful of minor leaks found by Coverity
+ - !2030 Fix more warnings
+ - !2031 Re-simplify exception handling on Windows
+ - !2032 gsocks5proxy: Handle EOF when reading from a stream
+ - !2033 Fix annotation of count arguments
+ - !2036 gmacros.h: use G_GNUC_CHECK_VERSION
+ - !2038 Fix more warnings
+ - !2039 Implement G_ANALYZER_NORETURN for Coverity
+ - !2040 Fix more warnings
+ - !2041 refcount: Clarify when the ref count ends up undefined
+ - !2042 grefcount: Clarify that the initial reference count is 1
+ - !2043 gmacros.h: use g_macro__has_attribute() where possible
+ - !2046 gerror: Clarify docs around message requirements
+ - !2047 Fix more warnings
+ - !2048 Fix more warnings
+ - !2049 Fix typo in g_socket_listener_accept_async()'s comment
+ - !2050 gdbus: document completion after idle action for g_dbus_connection_signal_unsubscribe()
+ - !2051 Add nullable annotations in GUnixMountEntry
+ - !2052 g_string_replace(): Fix documentation of 'limit' parameter
+ - !2054 docs: Fix formatting of code block
+ - !2055 Improve handling of FILENAME_MAX
+ - !2056 application: Unset the registered state after shutting down
+ - !2063 Fix more warnings
+ - !2066 gpattern: Register as Boxed type and support introspection for it
+ - !2067 gmacros: missing check if __STDC_VERSION__ is defined
+ - !2069 gdbus-tool: Actually use argv[0] basename as program name
+ - !2071 gstring: Cleanup documentation of g_string_replace
+ - !2074 Fix more warnings
+ - !2075 gdtlsconnection: Fix a check for a vfunc being implemented
+ - !2077 tls: add functions to get protocol version and ciphersuite name
+ - !2078 gthreadedresolver: don't ignore flags in lookup_by_name_with_flags
+ - !2080 guuid: fix shift operation to parse hex string in uuid_parse_string()
+ - !2081 Fix more warnings
+ - !2085 gcredentials.h: Fix comment typo
+ - !2087 gtlscertificate: make private key properties readable
+ - !2088 Fix more warnings
+ - !2090 docs: Standardize spelling of serializ*
+ - !2091 Fix more warnings (clang)
+ - !2098 grefcount: Optimise g_atomic_ref_count_dec
+ - !2099 gmacros.h: G_NORETURN: remove useless checks
+ - !2100 tests: Add missing return value check in string test
+ - !2101 Fix more warnings
+ - !2104 tests: Drop use of g_test_bug_base()
+ - !2105 tests: Use a temporary file in the bookmarkfile tests
+ - !2106 Fix more warnings
+ - !2108 glib spawn-singlethread test only if F_DUPFD_CLOEXEC is defined
+ - !2109 meson: Fix detection of static libintl on macOS
+ - !2112 gstrvbuilder: add addv and add_many to the API
+ - !2113 tls: expose cert details on GTlsCertificate
+ - !2119 Fix more warnings
+ - !2120 gdbusobjectmanagerclient: Call GetManagedObjects async
+ - !2123 gdbus: Add various missing (nullable) or (not nullable) annotations
+ - !2126 gtlspassword: Add flags signifying PIN type for PKCS#11
+ - !2127 gutils: ensure g_find_program_in_path() return an absolute path
+ - !2130 Revert "tests: Deactivate tls-bindings test suite for windows"
+ - !2139 gdbus, win32: Fix accidental dllexport in static builds
+ - !2142 tls: expose SAN details on GTlsCertificate
+ - !2143 compiling.xml: Don't recommend backticks
+ - !2144 pcre: Drop internal libpcre copy
+ - !2145 gunixmounts: Document NULL return value for g_unix_mount_for()
+ - !2152 tests: A few small improvements to GBytes tests
+ - !2153 docs: Fix annotations for optional arguments
+ - !2155 glocalfilemonitor: Avoid a deadlock on finalization
+ - !2162 testgdate: fix -Wmisleading-indentation warning
+ - !2166 gtlscertificate: Add more annotations to new properties
+ - !2167 g_value_set_string description: clarified (unified), that v_string is a copy.
+ - !2173 gasyncqueue: Add missing (nullable) annotation to free function
+ - !2174 data-to-c.py: generate new-line at the end of the file
* Translation updates:
+ - Chinese (China)
- English (United Kingdom)
+ - Hebrew
+ - Nepali
+ - Occitan (post 1500)
+ - Serbian
Overview of changes in GLib 2.68.0
diff --git a/README.md b/README.md
index 9ef3b3d6b..c53dd6f4d 100644
--- a/README.md
+++ b/README.md
@@ -47,3 +47,16 @@ Closes: #123
Otherwise, create a new merge request that introduces the change, filing a
separate issue is not required.
+
+## Default branch renamed to `main`
+
+The default development branch of GLib has been renamed to `main`. To update
+your local checkout, use:
+```sh
+git checkout master
+git branch -m master main
+git fetch
+git branch --unset-upstream
+git branch -u origin/main
+git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
+```
diff --git a/README.win32.md b/README.win32.md
index e67552270..17b36acbf 100644
--- a/README.win32.md
+++ b/README.win32.md
@@ -163,71 +163,7 @@ normally.
### Support for pre-2012 Visual Studio
-This release of GLib requires at least the Windows 8.0 SDK in order to be built
-successfully using Visual Studio, which means that building with Visual Studio
-2008 or 2010 is possible only with a special setup and must be done in the
-command line with Ninja. Please see
-https://devblogs.microsoft.com/cppblog/using-the-windows-software-development-kit-sdk-for-windows-8-consumer-preview-with-visual-studio-2010/
-for references; basically, assuming that your Windows 8.0 SDK is installed in
-`C:\Program Files (x86)\Windows Kits\8.0` (`$(WIN8SDKDIR)` in short), you need
-to ensure the following before invoking Meson to configure the build:
-
-- Your `%INCLUDE%` must not include the Windows 7.0/7.1 SDK include directories,
- and `$(WIN8SDKDIR)\include\um`, `$(WIN8SDKDIR)\include\um\share` and
- `$(WIN8SDKDIR)\include\winrt` (in this order) must be before your stock
- Visual Studio 2008/2010 header directories. If you have the DirectX SDK installed,
- you should remove its include directory from your `%INCLUDE%` as well.
-- You must replace the Windows 7.0/7.1 SDK library directory in `%LIB%` with the
- Windows 8.0 SDK library directory, i.e. `$(WIN8SDKDIR)\lib\win8\um\[x86|x64]`.
- If you have the DirectX SDK installed, you should remove its library directory
- from your `%INCLUDE%` as well.
-- You must replace the Windows 7.0/7.1 SDK tools directory from your `%PATH%` with
- the Windows 8.0 SDK tools directory, i.e. `$(WIN8SDKDIR)\bin\[x86|x64]`.
- If you have the DirectX SDK installed, you should remove its utility directory
- from your `%PATH%` as well.
-
-The Windows 8.0 SDK headers may contain an `roapi.h` that cannot be used under plain
-C, so to remedy that, change the following lines (around lines 55-57):
-
-```
-// RegisterActivationFactory/RevokeActivationFactory registration cookie
-typedef struct {} *RO_REGISTRATION_COOKIE;
-// RegisterActivationFactory/DllGetActivationFactory callback
-```
-
-to
-
-```
-// RegisterActivationFactory/RevokeActivationFactory registration cookie
-#ifdef __cplusplus
-typedef struct {} *RO_REGISTRATION_COOKIE;
-#else
-typedef struct _RO_REGISTRATION_COOKIE *RO_REGISTRATION_COOKIE; /* make this header includable in C files */
-#endif
-// RegisterActivationFactory/DllGetActivationFactory callback
-```
-
-This follows what is done in the Windows 8.1 SDK, which contains an `roapi.h`
-that is usable under plain C. Please note that you might need to copy that file
-into a location that is in your `%INCLUDE%` which precedes the include path for the
-Windows 8.0 SDK headers, if you do not have administrative privileges.
-
-### Visual Studio 2008 hacks
-
-- You need to run the following lines from your build directory, to embed the
- manifests that are generated during the build, assuming the built binaries
- are installed to `$(PREFIX)`, after a successful build/installation:
-
-```cmd
-> for /r %f in (*.dll.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;2
-> for /r %f in (*.exe.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;1
-```
-
-
-- If building for amd64/x86_64/x64, sometimes the compilation of sources may seem to hang, which
- is caused by an optimization issue in the 2008 x64 compiler. You need to use Task Manager to
- remove all running instances of `cl.exe`, which will cause the build process to terminate. Update
- the build flags of the sources that hang on compilation by changing its `"/O2"` flag to `"/O1"`
- in `build.ninja`, and retry the build, where things should continue to build normally. At the
- time of writing, this is needed for compiling `glib/gtestutils.c`, `gio/gsettings.c`,
- `gio/gsettingsschema.c`, `glib/tests/fileutils.c` and `gio/tests/gsubprocess-testprog.c`
+This release of GLib requires at least the Windows 8 SDK in order to be built
+successfully using Visual Studio, which means that it is no longer supported to
+build GLib with Visual Studio 2008 nor 2010. People that still need to use
+Visual Studio 2008 or 2010 should continue to use glib-2.66.x.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..3505b2abf
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,67 @@
+# Security policy for GLib
+
+ * [Supported Versions](#Supported-Versions)
+ * [Reporting a Vulnerability](#Reporting-a-Vulnerability)
+ * [Security Announcements](#Security-Announcements)
+ * [Acknowledgements](#Acknowledgements)
+
+## Supported Versions
+
+Upstream GLib only supports the most recent stable release series, and the
+current development release series. Any older stable release series are no
+longer supported, although they may still receive backported security updates
+in long-term support distributions. Such support is up to the distributions,
+though.
+
+Under GLib’s versioning scheme, stable release series have an *even* minor
+component (for example, 2.66.0, 2.66.1, 2.68.3), and development release series
+have an *odd* minor component (2.67.1, 2.69.0).
+
+## Reporting a Vulnerability
+
+If you think you've identified a security issue in GLib, GObject or GIO, please
+**do not** report the issue publicly via a mailing list, IRC, a public issue on
+the GitLab issue tracker, a merge request, or any other public venue.
+
+Instead, report a
+[*confidential* issue in the GitLab issue tracker](https://gitlab.gnome.org/GNOME/glib/-/issues/new?issue[confidential]=1),
+with the “This issue is confidential” box checked. Please include as many
+details as possible, including a minimal reproducible example of the issue, and
+an idea of how exploitable/severe you think it is.
+
+**Do not** provide a merge request to fix the issue, as there is currently no
+way to make confidential merge requests on gitlab.gnome.org. If you have patches
+which fix the security issue, please attach them to your confidential issue as
+patch files.
+
+Confidential issues are only visible to the reporter and the GLib maintainers.
+
+As per the [GNOME security policy](https://security.gnome.org/), the next steps
+are then:
+ * The report is triaged.
+ * Code is audited to find any potential similar problems.
+ * If it is determined, in consultation with the submitter, that a CVE is
+ required, the submitter obtains one via [cveform.mitre.org](https://cveform.mitre.org/).
+ * The fix is prepared for the development branch, and for the most recent
+ stable branch.
+ * The fix is submitted to the public repository.
+ * On the day the issue and fix are made public, an announcement is made on the
+ [public channels listed below](#Security-Announcements).
+ * A new release containing the fix is issued.
+
+## Security Announcements
+
+Security announcements are made publicly via the
+[`distributor` tag on discourse.gnome.org](https://discourse.gnome.org/tag/distributor)
+and cross-posted to the
+[distributor-list](https://mail.gnome.org/mailman/listinfo/distributor-list).
+
+Announcements for security issues with wide applicability or high impact may
+additionally be made via
+[oss-security@lists.openwall.com](https://www.openwall.com/lists/oss-security/).
+
+## Acknowledgements
+
+This text was partially based on the
+[github.com/containers security policy](https://github.com/containers/common/blob/HEAD/SECURITY.md),
+and partially based on the [flatpak security policy](https://github.com/flatpak/flatpak/blob/HEAD/SECURITY.md).
diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index 9cd3d0e39..a09d6d31d 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -389,6 +389,10 @@
<title>Index of new symbols in 2.68</title>
<xi:include href="xml/api-index-2.68.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-70" role="2.70">
+ <title>Index of new symbols in 2.70</title>
+ <xi:include href="xml/api-index-2.70.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index 945c26ade..250491a42 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -397,6 +397,8 @@ g_file_info_get_content_type
g_file_info_get_size
g_file_info_get_modification_time
g_file_info_get_modification_date_time
+g_file_info_get_access_date_time
+g_file_info_get_creation_date_time
g_file_info_get_symlink_target
g_file_info_get_etag
g_file_info_get_sort_order
@@ -415,6 +417,8 @@ g_file_info_set_content_type
g_file_info_set_size
g_file_info_set_modification_time
g_file_info_set_modification_date_time
+g_file_info_set_access_date_time
+g_file_info_set_creation_date_time
g_file_info_set_symlink_target
g_file_info_set_sort_order
g_file_attribute_matcher_new
@@ -2802,6 +2806,7 @@ g_dbus_is_name
g_dbus_is_unique_name
g_dbus_is_member_name
g_dbus_is_interface_name
+g_dbus_is_error_name
g_dbus_gvalue_to_gvariant
g_dbus_gvariant_to_gvalue
g_dbus_escape_object_path_bytestring
@@ -3663,16 +3668,19 @@ GTlsChannelBindingError
<SUBSECTION>
GTlsAuthenticationMode
GTlsCertificateFlags
+GTlsProtocolVersion
<SUBSECTION Standard>
G_TYPE_TLS_AUTHENTICATION_MODE
G_TYPE_TLS_CERTIFICATE_FLAGS
G_TYPE_TLS_CHANNEL_BINDING_ERROR
G_TYPE_TLS_ERROR
+G_TYPE_TLS_PROTOCOL_VERSION
g_tls_authentication_mode_get_type
g_tls_certificate_flags_get_type
g_tls_channel_binding_error_get_type
g_tls_channel_binding_error_quark
g_tls_error_get_type
+g_tls_protocol_version_get_type
</SECTION>
<SECTION>
@@ -3711,7 +3719,13 @@ g_tls_certificate_new_from_file
g_tls_certificate_new_from_files
g_tls_certificate_new_from_pkcs11_uris
g_tls_certificate_list_new_from_file
+g_tls_certificate_get_dns_names
+g_tls_certificate_get_ip_addresses
g_tls_certificate_get_issuer
+g_tls_certificate_get_issuer_name
+g_tls_certificate_get_not_valid_before
+g_tls_certificate_get_not_valid_after
+g_tls_certificate_get_subject_name
g_tls_certificate_verify
g_tls_certificate_is_same
<SUBSECTION Standard>
@@ -3750,6 +3764,8 @@ g_tls_connection_get_database
g_tls_connection_set_database
g_tls_connection_get_interaction
g_tls_connection_set_interaction
+g_tls_connection_get_protocol_version
+g_tls_connection_get_ciphersuite_name
<SUBSECTION>
g_tls_connection_handshake
g_tls_connection_handshake_async
@@ -3944,6 +3960,8 @@ g_dtls_connection_get_database
g_dtls_connection_set_database
g_dtls_connection_get_interaction
g_dtls_connection_set_interaction
+g_dtls_connection_get_protocol_version
+g_dtls_connection_get_ciphersuite_name
<SUBSECTION>
g_dtls_connection_handshake
g_dtls_connection_handshake_async
diff --git a/docs/reference/gio/gsettings.xml b/docs/reference/gio/gsettings.xml
index d7dc65db6..5f720d6e7 100644
--- a/docs/reference/gio/gsettings.xml
+++ b/docs/reference/gio/gsettings.xml
@@ -136,7 +136,7 @@ the dconf database.
<term><option>get</option></term>
<listitem><para>
Gets the value of <replaceable>KEY</replaceable>.
-The value is printed out as a serialised
+The value is printed out as a serialized
<link linkend="GVariant"><type>GVariant</type></link>.
</para></listitem>
</varlistentry>
@@ -175,7 +175,7 @@ Queries the description of valid values for <replaceable>KEY</replaceable>.
<term><option>set</option></term>
<listitem><para>
Sets the value of <replaceable>KEY</replaceable> to
-<replaceable>VALUE</replaceable>. The value is specified as a serialised
+<replaceable>VALUE</replaceable>. The value is specified as a serialized
<link linkend="GVariant"><type>GVariant</type></link>.
</para></listitem>
</varlistentry>
diff --git a/docs/reference/glib/building.xml b/docs/reference/glib/building.xml
index 9ff2fbfe7..d165c5c23 100644
--- a/docs/reference/glib/building.xml
+++ b/docs/reference/glib/building.xml
@@ -153,12 +153,9 @@
<listitem>
<para>
GRegex uses the <ulink url="http://www.pcre.org/">PCRE library</ulink>
- for regular expression matching. The default is to use the system
- version of PCRE, to reduce the chances of security fixes going out
- of sync. GLib additionally provides an internal copy of PCRE in case
- the system version is too old, or does not support UTF-8; the internal
- copy is patched to use GLib for memory management and to share the
- same Unicode tables.
+ for regular expression matching. The system version of PCRE is used,
+ unless not available (which is the case on Android), in which case a
+ fallback subproject is used.
</para>
</listitem>
<listitem>
@@ -236,45 +233,6 @@
</formalpara>
<formalpara>
- <title><option>-Dinternal_pcre=true</option></title>
-
- <para>
- Normally, GLib will be configured to use the system-supplied PCRE
- library if it is suitable, falling back to an internal version
- otherwise. If this option is specified, the internal version will always
- be used.
- </para>
- <para>
- Using the internal PCRE is the preferred solution if:
- <itemizedlist>
- <listitem>
- <para>
- your system has strict resource constraints; the system-supplied
- PCRE has a separated copy of the tables used for Unicode
- handling, whereas the internal copy shares the Unicode tables
- used by GLib.
- </para>
- </listitem>
- <listitem>
- <para>
- your system has PCRE built without some needed features,
- such as UTF-8 and Unicode support.
- </para>
- </listitem>
- <listitem>
- <para>
- you are planning to use both GRegex and PCRE API at the same
- time, either directly or indirectly through a dependency; PCRE
- uses some global variables for memory management and
- other features, and if both GLib and PCRE try to access them
- at the same time, this could lead to undefined behavior.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- </formalpara>
-
- <formalpara>
<title><option>-Dbsymbolic_functions=false</option> and
<option>-Dbsymbolic_functions=true</option></title>
diff --git a/docs/reference/glib/compiling.xml b/docs/reference/glib/compiling.xml
index 02971a60f..c7a058c5f 100644
--- a/docs/reference/glib/compiling.xml
+++ b/docs/reference/glib/compiling.xml
@@ -60,13 +60,13 @@ The difference between the two is that gmodule-2.0 adds
which is often not needed.
</para>
<para>
-The simplest way to compile a program is to use the "backticks"
-feature of the shell. If you enclose a command in backticks
-(<emphasis>not single quotes</emphasis>), then its output will
-be substituted into the command line before execution. So to
-compile a GLib Hello, World, you would type the following:
+The simplest way to compile a program is to use command substitution
+feature of a shell. A command written in the format
+<literal>$(command)</literal> gets substituted into the command line
+before execution. So to compile a GLib Hello, World, you would type
+the following:
<programlisting>
-$ cc hello.c `pkg-config --cflags --libs glib-2.0` -o hello
+$ cc hello.c $(pkg-config --cflags --libs glib-2.0) -o hello
</programlisting>
</para>
<note><para>
diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml
index e464fb792..2f5de9e31 100644
--- a/docs/reference/glib/glib-docs.xml
+++ b/docs/reference/glib/glib-docs.xml
@@ -288,6 +288,10 @@
<title>Index of new symbols in 2.68</title>
<xi:include href="xml/api-index-2.68.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-70" role="2.70">
+ <title>Index of new symbols in 2.70</title>
+ <xi:include href="xml/api-index-2.70.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 460a299bf..406041253 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -138,6 +138,7 @@ GLIB_VERSION_2_62
GLIB_VERSION_2_64
GLIB_VERSION_2_66
GLIB_VERSION_2_68
+GLIB_VERSION_2_70
GLIB_VERSION_CUR_STABLE
GLIB_VERSION_PREV_STABLE
GLIB_VERSION_MIN_REQUIRED
@@ -168,6 +169,7 @@ GLIB_AVAILABLE_ENUMERATOR_IN_2_62
GLIB_AVAILABLE_ENUMERATOR_IN_2_64
GLIB_AVAILABLE_ENUMERATOR_IN_2_66
GLIB_AVAILABLE_ENUMERATOR_IN_2_68
+GLIB_AVAILABLE_ENUMERATOR_IN_2_70
GLIB_AVAILABLE_IN_ALL
GLIB_AVAILABLE_IN_2_26
GLIB_AVAILABLE_IN_2_28
@@ -191,6 +193,7 @@ GLIB_AVAILABLE_IN_2_62
GLIB_AVAILABLE_IN_2_64
GLIB_AVAILABLE_IN_2_66
GLIB_AVAILABLE_IN_2_68
+GLIB_AVAILABLE_IN_2_70
GLIB_AVAILABLE_MACRO_IN_2_26
GLIB_AVAILABLE_MACRO_IN_2_28
GLIB_AVAILABLE_MACRO_IN_2_30
@@ -213,12 +216,14 @@ GLIB_AVAILABLE_MACRO_IN_2_62
GLIB_AVAILABLE_MACRO_IN_2_64
GLIB_AVAILABLE_MACRO_IN_2_66
GLIB_AVAILABLE_MACRO_IN_2_68
+GLIB_AVAILABLE_MACRO_IN_2_70
GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
GLIB_AVAILABLE_STATIC_INLINE_IN_2_66
GLIB_AVAILABLE_STATIC_INLINE_IN_2_68
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
GLIB_AVAILABLE_TYPE_IN_2_26
GLIB_AVAILABLE_TYPE_IN_2_28
GLIB_AVAILABLE_TYPE_IN_2_30
@@ -241,6 +246,7 @@ GLIB_AVAILABLE_TYPE_IN_2_62
GLIB_AVAILABLE_TYPE_IN_2_64
GLIB_AVAILABLE_TYPE_IN_2_66
GLIB_AVAILABLE_TYPE_IN_2_68
+GLIB_AVAILABLE_TYPE_IN_2_70
GLIB_DEPRECATED_ENUMERATOR
GLIB_DEPRECATED_ENUMERATOR_FOR
GLIB_DEPRECATED_ENUMERATOR_IN_2_26
@@ -287,6 +293,8 @@ GLIB_DEPRECATED_ENUMERATOR_IN_2_66
GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR
GLIB_DEPRECATED_ENUMERATOR_IN_2_68
GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_70
+GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR
GLIB_DEPRECATED_IN_2_26
GLIB_DEPRECATED_IN_2_26_FOR
GLIB_DEPRECATED_IN_2_28
@@ -331,6 +339,8 @@ GLIB_DEPRECATED_IN_2_66
GLIB_DEPRECATED_IN_2_66_FOR
GLIB_DEPRECATED_IN_2_68
GLIB_DEPRECATED_IN_2_68_FOR
+GLIB_DEPRECATED_IN_2_70
+GLIB_DEPRECATED_IN_2_70_FOR
GLIB_DEPRECATED_MACRO
GLIB_DEPRECATED_MACRO_FOR
GLIB_DEPRECATED_MACRO_IN_2_26
@@ -377,6 +387,8 @@ GLIB_DEPRECATED_MACRO_IN_2_66
GLIB_DEPRECATED_MACRO_IN_2_66_FOR
GLIB_DEPRECATED_MACRO_IN_2_68
GLIB_DEPRECATED_MACRO_IN_2_68_FOR
+GLIB_DEPRECATED_MACRO_IN_2_70
+GLIB_DEPRECATED_MACRO_IN_2_70_FOR
GLIB_DEPRECATED_TYPE
GLIB_DEPRECATED_TYPE_FOR
GLIB_DEPRECATED_TYPE_IN_2_26
@@ -423,6 +435,8 @@ GLIB_DEPRECATED_TYPE_IN_2_66
GLIB_DEPRECATED_TYPE_IN_2_66_FOR
GLIB_DEPRECATED_TYPE_IN_2_68
GLIB_DEPRECATED_TYPE_IN_2_68_FOR
+GLIB_DEPRECATED_TYPE_IN_2_70
+GLIB_DEPRECATED_TYPE_IN_2_70_FOR
GLIB_VERSION_CUR_STABLE
GLIB_VERSION_PREV_STABLE
</SECTION>
@@ -735,10 +749,25 @@ G_ANALYZER_ANALYZING
G_ANALYZER_NORETURN
g_autoptr_cleanup_generic_gfree
glib_typeof
-glib_typeof_2_68
g_macro__has_attribute
g_macro__has_builtin
g_macro__has_feature
+g_macro__has_extension
+g_macro__has_attribute___alloc_size__
+g_macro__has_attribute___const__
+g_macro__has_attribute___deprecated__
+g_macro__has_attribute___format__
+g_macro__has_attribute___format_arg__
+g_macro__has_attribute___malloc__
+g_macro__has_attribute___no_instrument_function__
+g_macro__has_attribute___noreturn__
+g_macro__has_attribute___pure__
+g_macro__has_attribute___sentinel__
+g_macro__has_attribute___unused__
+g_macro__has_attribute_fallthrough
+g_macro__has_attribute_may_alias
+g_macro__has_attribute___noinline__
+g_macro__has_attribute_warn_unused_result
</SECTION>
<SECTION>
@@ -756,6 +785,7 @@ g_set_error_literal
g_propagate_error
g_clear_error
g_prefix_error
+g_prefix_error_literal
g_propagate_prefixed_error
<SUBSECTION>
GErrorInitFunc
@@ -910,6 +940,9 @@ g_source_remove_by_user_data
GClearHandleFunc
g_clear_handle_id
+<SUBSECTION>
+g_steal_fd
+
<SUBSECTION Private>
GLIB_HAVE_ALLOCA_H
alloca
@@ -1138,6 +1171,7 @@ g_once_init_enter_impl
<FILE>thread_pools</FILE>
GThreadPool
g_thread_pool_new
+g_thread_pool_new_full
g_thread_pool_push
g_thread_pool_set_max_threads
g_thread_pool_get_max_threads
@@ -1392,6 +1426,9 @@ GPatternSpec
g_pattern_spec_new
g_pattern_spec_free
g_pattern_spec_equal
+g_pattern_spec_copy
+g_pattern_spec_match
+g_pattern_spec_match_string
g_pattern_match
g_pattern_match_string
g_pattern_match_simple
@@ -1531,6 +1568,7 @@ g_spawn_async_with_pipes_and_fds
g_spawn_async
g_spawn_sync
G_SPAWN_EXIT_ERROR
+g_spawn_check_wait_status
g_spawn_check_exit_status
g_spawn_command_line_async
g_spawn_command_line_sync
@@ -1613,6 +1651,7 @@ GOptionArg
GOptionFlags
G_OPTION_REMAINING
GOptionEntry
+G_OPTION_ENTRY_NULL
g_option_context_add_main_entries
GOptionGroup
g_option_context_add_group
@@ -1828,6 +1867,8 @@ g_strv_builder_new
g_strv_builder_ref
g_strv_builder_unref
g_strv_builder_add
+g_strv_builder_addv
+g_strv_builder_add_many
g_strv_builder_end
<SUBSECTION>
@@ -2989,6 +3030,7 @@ g_bytes_new_static
g_bytes_new_with_free_func
g_bytes_new_from_bytes
g_bytes_get_data
+g_bytes_get_region
g_bytes_get_size
g_bytes_hash
g_bytes_equal
@@ -3038,6 +3080,7 @@ g_tree_lower_bound
g_tree_upper_bound
g_tree_remove
g_tree_steal
+g_tree_remove_all
g_tree_destroy
</SECTION>
diff --git a/docs/reference/glib/gvariant-varargs.xml b/docs/reference/glib/gvariant-varargs.xml
index cd9002ca5..bab12e31e 100644
--- a/docs/reference/glib/gvariant-varargs.xml
+++ b/docs/reference/glib/gvariant-varargs.xml
@@ -263,7 +263,7 @@
<para>
Used as a prefix for a GVariant type string (not a prefix for a format string, so <literal>&amp;s</literal> is
a valid format string but <literal>&amp;@s</literal> is not).
- Denotes that a C pointer to serialised data
+ Denotes that a C pointer to serialized data
should be used in place of the normal C type. See
<link linkend='gvariant-format-strings-pointers'>Pointers</link> below.
</para>
@@ -946,7 +946,7 @@ data = g_variant_new_parsed ("(%o, {'brightness': {'value': <%i>, 'max': <%i>}})
</para>
<para>
- The '<code>&amp;</code>' character is used to indicate that serialised data should be directly exchanged via a
+ The '<code>&amp;</code>' character is used to indicate that serialized data should be directly exchanged via a
pointer.
</para>
<para>
@@ -954,7 +954,7 @@ data = g_variant_new_parsed ("(%o, {'brightness': {'value': <%i>, 'max': <%i>}})
'<literal>&amp;o</literal>' or '<code>&amp;g</code>'). For
<link linkend='g-variant-new'><function>g_variant_new()</function></link> this has absolutely no effect. The string
is collected and duplicated normally. For <link linkend='g-variant-get'><function>g_variant_get()</function></link>
- it means that instead of creating a newly allocated copy of the string, a pointer to the serialised data is
+ it means that instead of creating a newly allocated copy of the string, a pointer to the serialized data is
returned. This pointer should not be freed. Validity checks are performed to ensure that the string data will
always be properly nul-terminated.
</para>
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
index 43c273855..838a4f777 100644
--- a/docs/reference/glib/meson.build
+++ b/docs/reference/glib/meson.build
@@ -25,8 +25,6 @@ if get_option('gtk_doc')
'gtrace-private.h',
'glib-mirroring-tab',
'gnulib',
- 'pcre',
- 'update-pcre',
'gbytesprivate.h',
'gvariant-internal.h',
'gvariant-serialiser.h',
diff --git a/docs/reference/glib/running.xml b/docs/reference/glib/running.xml
index aaafddf1d..80a8da097 100644
--- a/docs/reference/glib/running.xml
+++ b/docs/reference/glib/running.xml
@@ -201,8 +201,11 @@ How to run and debug your GLib application
reproduced with <literal>G_SLICE=always-malloc</literal>, but will
be caught by <literal>G_SLICE=debug-blocks</literal> is as follows:
<programlisting>
- void *slist = g_slist_alloc (); /* void* gives up type-safety */
- g_list_free (slist); /* corruption: sizeof (GSList) != sizeof (GList) */
+ /* void* gives up type-safety */
+ void *slist = g_slist_alloc ();
+
+ /* corruption: sizeof (GSList) != sizeof (GList) */
+ g_list_free (slist);
</programlisting></para>
</listitem>
</varlistentry>
diff --git a/docs/reference/gobject/gobject-docs.xml b/docs/reference/gobject/gobject-docs.xml
index ddbc9f274..e8e7c76d9 100644
--- a/docs/reference/gobject/gobject-docs.xml
+++ b/docs/reference/gobject/gobject-docs.xml
@@ -208,6 +208,10 @@
<title>Index of new symbols in 2.68</title>
<xi:include href="xml/api-index-2.68.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-70" role="2.70">
+ <title>Index of new symbols in 2.70</title>
+ <xi:include href="xml/api-index-2.70.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index 54fbccaf8..685529708 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -268,6 +268,7 @@ GParameter
g_object_ref
g_object_unref
g_object_ref_sink
+g_object_take_ref
g_set_object
g_clear_object
GInitiallyUnowned
@@ -411,6 +412,7 @@ G_TYPE_THREAD
G_TYPE_OPTION_GROUP
G_TYPE_URI
G_TYPE_TREE
+G_TYPE_PATTERN_SPEC
<SUBSECTION Standard>
G_TYPE_IS_BOXED
@@ -446,6 +448,7 @@ g_thread_get_type
g_option_group_get_type
g_uri_get_type
g_tree_get_type
+g_pattern_spec_get_type
</SECTION>
<SECTION>
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
index 3f09be555..53ca12ff8 100644
--- a/docs/reference/meson.build
+++ b/docs/reference/meson.build
@@ -7,7 +7,7 @@
stable_2_series_versions = [
'26', '28', '30', '32', '34', '36', '38',
'40', '42', '44', '46', '48', '50', '52', '54', '56', '58',
- '60', '62', '64', '66', '68',
+ '60', '62', '64', '66', '68', '70',
]
ignore_decorators = [
diff --git a/fuzzing/README.md b/fuzzing/README.md
index 16f5a05bc..21565e396 100644
--- a/fuzzing/README.md
+++ b/fuzzing/README.md
@@ -40,7 +40,7 @@ $ DIR/fuzzing/fuzz_target_name FILE
Correct MSAN instrumentation is [difficult to achieve](https://clang.llvm.org/docs/MemorySanitizer.html#handling-external-code) locally, so false positives are very likely to mask the actual bug.
-If need be, [you can still reproduce](https://github.com/google/oss-fuzz/blob/master/docs/reproducing.md#building-using-docker) those bugs with the oss-fuzz provided docker images.
+If need be, [you can still reproduce](https://google.github.io/oss-fuzz/advanced-topics/reproducing/#building-using-docker) those bugs with the oss-fuzz provided docker images.
###### There are no file/function names in the stack trace.
diff --git a/fuzzing/driver.c b/fuzzing/driver.c
index f6d2396db..296ce5710 100644
--- a/fuzzing/driver.c
+++ b/fuzzing/driver.c
@@ -30,6 +30,7 @@ main (int argc, char **argv)
LLVMFuzzerTestOneInput (buf, len);
free (buf);
+ fclose (f);
printf ("Done!\n");
return 0;
}
diff --git a/fuzzing/fuzz_canonicalize_filename.c b/fuzzing/fuzz_canonicalize_filename.c
new file mode 100644
index 000000000..86b323ef9
--- /dev/null
+++ b/fuzzing/fuzz_canonicalize_filename.c
@@ -0,0 +1,19 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+ unsigned char *nul_terminated_data = NULL;
+ gchar *canonicalized = NULL;
+
+ fuzz_set_logging_func ();
+
+ /* ignore @size (g_canonicalize_filename() doesn’t support it); ensure @data is nul-terminated */
+ nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size);
+ canonicalized = g_canonicalize_filename ((const gchar *) nul_terminated_data, "/");
+ g_free (nul_terminated_data);
+
+ g_free (canonicalized);
+
+ return 0;
+}
diff --git a/fuzzing/fuzz_paths.c b/fuzzing/fuzz_paths.c
new file mode 100644
index 000000000..fbed84771
--- /dev/null
+++ b/fuzzing/fuzz_paths.c
@@ -0,0 +1,32 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+ unsigned char *nul_terminated_data = NULL;
+ const gchar *skipped_root;
+ gchar *basename = NULL, *dirname = NULL;
+
+ fuzz_set_logging_func ();
+
+ /* ignore @size (none of the functions support it); ensure @data is nul-terminated */
+ nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size);
+
+ g_path_is_absolute ((const gchar *) nul_terminated_data);
+
+ skipped_root = g_path_skip_root ((const gchar *) nul_terminated_data);
+ g_assert (skipped_root == NULL || skipped_root >= (const gchar *) nul_terminated_data);
+ g_assert (skipped_root == NULL || skipped_root <= (const gchar *) nul_terminated_data + size);
+
+ basename = g_path_get_basename ((const gchar *) nul_terminated_data);
+ g_assert (strcmp (basename, ".") == 0 || strlen (basename) <= size);
+
+ dirname = g_path_get_dirname ((const gchar *) nul_terminated_data);
+ g_assert (strcmp (dirname, ".") == 0 || strlen (dirname) <= size);
+
+ g_free (nul_terminated_data);
+ g_free (dirname);
+ g_free (basename);
+
+ return 0;
+}
diff --git a/fuzzing/meson.build b/fuzzing/meson.build
index a40321200..c60dcf446 100644
--- a/fuzzing/meson.build
+++ b/fuzzing/meson.build
@@ -1,5 +1,6 @@
fuzz_targets = [
'fuzz_bookmark',
+ 'fuzz_canonicalize_filename',
'fuzz_date_parse',
'fuzz_date_time_new_from_iso8601',
'fuzz_dbus_message',
@@ -9,6 +10,7 @@ fuzz_targets = [
'fuzz_key',
'fuzz_network_address_parse',
'fuzz_network_address_parse_uri',
+ 'fuzz_paths',
'fuzz_uri_escape',
'fuzz_uri_parse',
'fuzz_uri_parse_params',
@@ -22,7 +24,7 @@ extra_sources = []
extra_c_args = cc.get_supported_arguments('-Werror=unused-function')
# Links in a static library provided by oss-fuzz, else a standalone driver.
-# https://github.com/google/oss-fuzz/blob/master/docs/new_project_guide.md#buildsh-script-environment
+# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh-script-environment
fuzzing_engine = cxx.find_library('FuzzingEngine', required : get_option('oss_fuzz'))
if fuzzing_engine.found()
deps += fuzzing_engine
diff --git a/gio/data-to-c.py b/gio/data-to-c.py
index 1724f7dd1..8407fb4af 100755
--- a/gio/data-to-c.py
+++ b/gio/data-to-c.py
@@ -1,12 +1,13 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import sys
if len(sys.argv) < 4:
print("Usage: {0} <filename> <variable> <output>")
-with open(sys.argv[1], "rb") as f:
- in_data = f.read().decode("utf-8", "backslashreplace")
+with open(sys.argv[1], "r", encoding="utf-8", errors="backslashreplace") as f:
+ in_data = f.read()
+
b = [r"\x{:02x}".format(ord(c)) for c in in_data]
out_data = 'const char {0}[] = "'.format(sys.argv[2])
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 3720146af..cbc467a92 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -155,13 +155,13 @@
* respectively.
*
* For an example of opening files with a GApplication, see
- * [gapplication-example-open.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-open.c).
+ * [gapplication-example-open.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-open.c).
*
* For an example of using actions with GApplication, see
- * [gapplication-example-actions.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-actions.c).
+ * [gapplication-example-actions.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-actions.c).
*
* For an example of using extra D-Bus hooks with GApplication, see
- * [gapplication-example-dbushooks.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-dbushooks.c).
+ * [gapplication-example-dbushooks.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-dbushooks.c).
*/
/**
@@ -543,7 +543,7 @@ g_application_parse_command_line (GApplication *application,
GOptionEntry entries[] = {
{ "gapplication-service", '\0', 0, G_OPTION_ARG_NONE, &become_service,
N_("Enter GApplication service mode (use from D-Bus service files)"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
g_option_group_add_entries (gapplication_group, entries);
@@ -555,7 +555,7 @@ g_application_parse_command_line (GApplication *application,
GOptionEntry entries[] = {
{ "gapplication-app-id", '\0', 0, G_OPTION_ARG_STRING, &app_id,
N_("Override the application’s ID"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
g_option_group_add_entries (gapplication_group, entries);
@@ -567,7 +567,7 @@ g_application_parse_command_line (GApplication *application,
GOptionEntry entries[] = {
{ "gapplication-replace", '\0', 0, G_OPTION_ARG_NONE, &replace,
N_("Replace the running instance"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
g_option_group_add_entries (gapplication_group, entries);
@@ -729,7 +729,11 @@ g_application_add_main_option_entries (GApplication *application,
for (i = 0; entries[i].long_name; i++)
{
- GOptionEntry my_entries[2] = { { NULL }, { NULL } };
+ GOptionEntry my_entries[2] =
+ {
+ G_OPTION_ENTRY_NULL,
+ G_OPTION_ENTRY_NULL
+ };
my_entries[0] = entries[i];
if (!my_entries[0].arg_data)
@@ -778,7 +782,7 @@ g_application_add_main_option (GApplication *application,
gchar *dup_string;
GOptionEntry my_entry[2] = {
{ NULL, short_name, flags, arg, NULL, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
g_return_if_fail (G_IS_APPLICATION (application));
@@ -2395,7 +2399,7 @@ g_application_open (GApplication *application,
* and override local_command_line(). In this case, you most likely want
* to return %TRUE from your local_command_line() implementation to
* suppress the default handling. See
- * [gapplication-example-cmdline2.c][gapplication-example-cmdline2]
+ * [gapplication-example-cmdline2.c][https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline2.c]
* for an example.
*
* If, after the above is done, the use count of the application is zero
@@ -2524,7 +2528,12 @@ g_application_run (GApplication *application,
context = g_main_context_default ();
acquired_context = g_main_context_acquire (context);
- g_return_val_if_fail (acquired_context, 0);
+ if (!acquired_context)
+ {
+ g_critical ("g_application_run() cannot acquire the default main context because it is already acquired by another thread!");
+ g_strfreev (arguments);
+ return 1;
+ }
if (!G_APPLICATION_GET_CLASS (application)
->local_command_line (application, &arguments, &status))
@@ -2573,6 +2582,13 @@ g_application_run (GApplication *application,
if (application->priv->impl)
{
+ if (application->priv->is_registered)
+ {
+ application->priv->is_registered = FALSE;
+
+ g_object_notify (G_OBJECT (application), "is-registered");
+ }
+
g_application_impl_flush (application->priv->impl);
g_application_impl_destroy (application->priv->impl);
application->priv->impl = NULL;
@@ -2816,6 +2832,8 @@ g_application_quit (GApplication *application)
*
* To cancel the busy indication, use g_application_unmark_busy().
*
+ * The application must be registered before calling this function.
+ *
* Since: 2.38
**/
void
@@ -2824,6 +2842,7 @@ g_application_mark_busy (GApplication *application)
gboolean was_busy;
g_return_if_fail (G_IS_APPLICATION (application));
+ g_return_if_fail (application->priv->is_registered);
was_busy = (application->priv->busy_count > 0);
application->priv->busy_count++;
diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c
index 7d3f0e665..741aa97f1 100644
--- a/gio/gapplicationcommandline.c
+++ b/gio/gapplicationcommandline.c
@@ -104,7 +104,7 @@
* }
* ]|
* The complete example can be found here:
- * [gapplication-example-cmdline.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline.c)
+ * [gapplication-example-cmdline.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline.c)
*
* In more complicated cases, the handling of the comandline can be
* split between the launcher and the primary instance.
@@ -155,7 +155,7 @@
* instance.
*
* The complete example can be found here:
- * [gapplication-example-cmdline2.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline2.c)
+ * [gapplication-example-cmdline2.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline2.c)
*
* If handling the commandline requires a lot of work, it may
* be better to defer it.
@@ -197,7 +197,7 @@
* hold the application until you are done with the commandline.
*
* The complete example can be found here:
- * [gapplication-example-cmdline3.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c)
+ * [gapplication-example-cmdline3.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline3.c)
*/
/**
diff --git a/gio/gcredentials.h b/gio/gcredentials.h
index 25cebf2b4..b61ab786b 100644
--- a/gio/gcredentials.h
+++ b/gio/gcredentials.h
@@ -82,4 +82,4 @@ gboolean g_credentials_set_unix_user (GCredentials *credentials,
G_END_DECLS
-#endif /* __G_DBUS_PROXY_H__ */
+#endif /* __G_CREDENTIALS_H__ */
diff --git a/gio/gdbus-tool.c b/gio/gdbus-tool.c
index 1f9e308d5..f44253804 100644
--- a/gio/gdbus-tool.c
+++ b/gio/gdbus-tool.c
@@ -145,7 +145,7 @@ modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command)
remove_arg (1, argc, argv);
program_name = g_path_get_basename ((*argv)[0]);
- s = g_strdup_printf ("%s %s", (*argv)[0], command);
+ s = g_strdup_printf ("%s %s", program_name, command);
(*argv)[0] = s;
g_free (program_name);
}
@@ -403,7 +403,7 @@ static const GOptionEntry connection_entries[] =
{ "system", 'y', 0, G_OPTION_ARG_NONE, &opt_connection_system, N_("Connect to the system bus"), NULL},
{ "session", 'e', 0, G_OPTION_ARG_NONE, &opt_connection_session, N_("Connect to the session bus"), NULL},
{ "address", 'a', 0, G_OPTION_ARG_STRING, &opt_connection_address, N_("Connect to given D-Bus address"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static GOptionGroup *
@@ -593,7 +593,7 @@ static const GOptionEntry emit_entries[] =
{ "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_emit_dest, N_("Optional destination for signal (unique name)"), NULL},
{ "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_emit_object_path, N_("Object path to emit signal on"), NULL},
{ "signal", 's', 0, G_OPTION_ARG_STRING, &opt_emit_signal, N_("Signal and interface name"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gboolean
@@ -894,7 +894,7 @@ static const GOptionEntry call_entries[] =
{ "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_call_object_path, N_("Object path to invoke method on"), NULL},
{ "method", 'm', 0, G_OPTION_ARG_STRING, &opt_call_method, N_("Method and interface name"), NULL},
{ "timeout", 't', 0, G_OPTION_ARG_INT, &opt_call_timeout, N_("Timeout in seconds"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gboolean
@@ -1688,7 +1688,7 @@ static const GOptionEntry introspect_entries[] =
{ "xml", 'x', 0, G_OPTION_ARG_NONE, &opt_introspect_xml, N_("Print XML"), NULL},
{ "recurse", 'r', 0, G_OPTION_ARG_NONE, &opt_introspect_recurse, N_("Introspect children"), NULL},
{ "only-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_introspect_only_properties, N_("Only print properties"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gboolean
@@ -1984,7 +1984,7 @@ static const GOptionEntry monitor_entries[] =
{
{ "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_monitor_dest, N_("Destination name to monitor"), NULL},
{ "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_monitor_object_path, N_("Object path to monitor"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gboolean
@@ -2195,7 +2195,7 @@ static const GOptionEntry wait_entries[] =
{ "timeout", 't', 0, G_OPTION_ARG_INT64, &opt_wait_timeout_secs,
N_("Timeout to wait for before exiting with an error (seconds); 0 for "
"no timeout (default)"), "SECS" },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index a341023df..f873be282 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -1082,7 +1082,7 @@ get_session_address_dbus_launch (GError **error)
gchar *command_line;
gchar *launch_stdout;
gchar *launch_stderr;
- gint exit_status;
+ gint wait_status;
gchar *old_dbus_verbose;
gboolean restore_dbus_verbose;
@@ -1146,13 +1146,13 @@ get_session_address_dbus_launch (GError **error)
if (!g_spawn_command_line_sync (command_line,
&launch_stdout,
&launch_stderr,
- &exit_status,
+ &wait_status,
error))
{
goto out;
}
- if (!g_spawn_check_exit_status (exit_status, error))
+ if (!g_spawn_check_wait_status (wait_status, error))
{
g_prefix_error (error, _("Error spawning command line “%s”: "), command_line);
goto out;
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index c430f0cf0..74c178dbf 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -960,7 +960,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
- "The given guid '%s' is not valid",
+ "The given GUID '%s' is not valid",
guid);
goto out;
}
@@ -1007,6 +1007,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
g_propagate_error (error, local_error);
goto out;
}
+ g_clear_error (&local_error);
}
else
{
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index a37611275..8ce70a93d 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -166,22 +166,22 @@
* ## An example D-Bus server # {#gdbus-server}
*
* Here is an example for a D-Bus server:
- * [gdbus-example-server.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-server.c)
+ * [gdbus-example-server.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-server.c)
*
* ## An example for exporting a subtree # {#gdbus-subtree-server}
*
* Here is an example for exporting a subtree:
- * [gdbus-example-subtree.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-subtree.c)
+ * [gdbus-example-subtree.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-subtree.c)
*
* ## An example for file descriptor passing # {#gdbus-unix-fd-client}
*
* Here is an example for passing UNIX file descriptors:
- * [gdbus-unix-fd-client.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-unix-fd-client.c)
+ * [gdbus-unix-fd-client.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-unix-fd-client.c)
*
* ## An example for exporting a GObject # {#gdbus-export}
*
* Here is an example for exporting a #GObject:
- * [gdbus-example-export.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-export.c)
+ * [gdbus-example-export.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-export.c)
*/
/* ---------------------------------------------------------------------------------------------------- */
@@ -386,7 +386,7 @@ struct _GDBusConnection
*/
gchar *bus_unique_name;
- /* The GUID returned by the other side if we authenticed as a client or
+ /* The GUID returned by the other side if we authenticated as a client or
* the GUID to use if authenticating as a server.
* Read-only after initable_init(), so it may be read if you either
* hold @init_lock or check for initialization first.
@@ -902,6 +902,15 @@ g_dbus_connection_class_init (GDBusConnectionClass *klass)
* of the other peer here after the connection has been successfully
* initialized.
*
+ * Note that the
+ * [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses)
+ * uses the term ‘UUID’ to refer to this, whereas GLib consistently uses the
+ * term ‘GUID’ for historical reasons.
+ *
+ * Despite its name, the format of #GDBusConnection:guid does not follow
+ * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) or the Microsoft
+ * GUID format.
+ *
* Since: 2.26
*/
g_object_class_install_property (gobject_class,
@@ -1610,7 +1619,6 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
guchar *blob;
gsize blob_size;
guint32 serial_to_use;
- gboolean ret;
CONNECTION_ENSURE_LOCK (connection);
@@ -1619,9 +1627,6 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
/* TODO: check all necessary headers are present */
- ret = FALSE;
- blob = NULL;
-
if (out_serial != NULL)
*out_serial = 0;
@@ -1633,14 +1638,14 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
if (!check_unclosed (connection,
(flags & SEND_MESSAGE_FLAGS_INITIALIZING) ? MAY_BE_UNINITIALIZED : 0,
error))
- goto out;
+ return FALSE;
blob = g_dbus_message_to_blob (message,
&blob_size,
connection->capabilities,
error);
if (blob == NULL)
- goto out;
+ return FALSE;
if (flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL)
serial_to_use = g_dbus_message_get_serial (message);
@@ -1686,18 +1691,13 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
g_dbus_message_set_serial (message, serial_to_use);
g_dbus_message_lock (message);
+
_g_dbus_worker_send_message (connection->worker,
message,
- (gchar*) blob,
+ (gchar*) blob, /* transfer ownership */
blob_size);
- blob = NULL; /* since _g_dbus_worker_send_message() steals the blob */
-
- ret = TRUE;
- out:
- g_free (blob);
-
- return ret;
+ return TRUE;
}
/**
@@ -2202,6 +2202,24 @@ typedef struct
GMainContext *context;
} FilterData;
+static void
+filter_data_destroy (FilterData *filter, gboolean notify_sync)
+{
+ if (notify_sync)
+ {
+ if (filter->user_data_free_func != NULL)
+ filter->user_data_free_func (filter->user_data);
+ }
+ else
+ {
+ call_destroy_notify (filter->context,
+ filter->user_data_free_func,
+ filter->user_data);
+ }
+ g_main_context_unref (filter->context);
+ g_free (filter);
+}
+
/* requires CONNECTION_LOCK */
static FilterData **
copy_filter_list (GPtrArray *filters)
@@ -2230,13 +2248,7 @@ free_filter_list (FilterData **filters)
{
filters[n]->ref_count--;
if (filters[n]->ref_count == 0)
- {
- call_destroy_notify (filters[n]->context,
- filters[n]->user_data_free_func,
- filters[n]->user_data);
- g_main_context_unref (filters[n]->context);
- g_free (filters[n]);
- }
+ filter_data_destroy (filters[n], FALSE);
}
g_free (filters);
}
@@ -3179,16 +3191,9 @@ static void
purge_all_filters (GDBusConnection *connection)
{
guint n;
- for (n = 0; n < connection->filters->len; n++)
- {
- FilterData *data = connection->filters->pdata[n];
- call_destroy_notify (data->context,
- data->user_data_free_func,
- data->user_data);
- g_main_context_unref (data->context);
- g_free (data);
- }
+ for (n = 0; n < connection->filters->len; n++)
+ filter_data_destroy (connection->filters->pdata[n], FALSE);
}
/**
@@ -3238,12 +3243,7 @@ g_dbus_connection_remove_filter (GDBusConnection *connection,
/* do free without holding lock */
if (to_destroy != NULL)
- {
- if (to_destroy->user_data_free_func != NULL)
- to_destroy->user_data_free_func (to_destroy->user_data);
- g_main_context_unref (to_destroy->context);
- g_free (to_destroy);
- }
+ filter_data_destroy (to_destroy, TRUE);
else if (!found)
{
g_warning ("g_dbus_connection_remove_filter: No filter found for filter_id %d", filter_id);
@@ -3724,6 +3724,9 @@ unsubscribe_id_internal (GDBusConnection *connection,
* g_dbus_connection_signal_subscribe() is called, in order to avoid memory
* leaks through callbacks queued on the #GMainContext after it’s stopped being
* iterated.
+ * Alternatively, any idle source with a priority lower than %G_PRIORITY_DEFAULT
+ * that was scheduled after unsubscription, also indicates that all resources
+ * of this subscription are released.
*
* Since: 2.26
*/
@@ -5058,7 +5061,8 @@ validate_and_maybe_schedule_method_call (GDBusConnection *connection,
static gboolean
obj_message_func (GDBusConnection *connection,
ExportedObject *eo,
- GDBusMessage *message)
+ GDBusMessage *message,
+ gboolean *object_found)
{
const gchar *interface_name;
const gchar *member;
@@ -5094,6 +5098,10 @@ obj_message_func (GDBusConnection *connection,
ei->user_data);
goto out;
}
+ else
+ {
+ *object_found = TRUE;
+ }
}
if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Introspectable") == 0 &&
@@ -7119,6 +7127,7 @@ distribute_method_call (GDBusConnection *connection,
const gchar *path;
gchar *subtree_path;
gchar *needle;
+ gboolean object_found = FALSE;
g_assert (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL);
@@ -7160,7 +7169,7 @@ distribute_method_call (GDBusConnection *connection,
eo = g_hash_table_lookup (connection->map_object_path_to_eo, object_path);
if (eo != NULL)
{
- if (obj_message_func (connection, eo, message))
+ if (obj_message_func (connection, eo, message, &object_found))
goto out;
}
@@ -7185,11 +7194,22 @@ distribute_method_call (GDBusConnection *connection,
goto out;
/* if we end up here, the message has not been not handled - so return an error saying this */
- reply = g_dbus_message_new_method_error (message,
+ if (object_found == TRUE)
+ {
+ reply = g_dbus_message_new_method_error (message,
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ _("No such interface “%s” on object at path %s"),
+ interface_name,
+ object_path);
+ }
+ else
+ {
+ reply = g_dbus_message_new_method_error (message,
"org.freedesktop.DBus.Error.UnknownMethod",
- _("No such interface “%s” on object at path %s"),
- interface_name,
+ _("Object does not exist at path “%s”"),
object_path);
+ }
+
g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
g_object_unref (reply);
diff --git a/gio/gdbusintrospection.c b/gio/gdbusintrospection.c
index f35b2fb44..d6aa445d5 100644
--- a/gio/gdbusintrospection.c
+++ b/gio/gdbusintrospection.c
@@ -98,7 +98,7 @@ typedef struct
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -118,7 +118,7 @@ g_dbus_node_info_ref (GDBusNodeInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -138,7 +138,7 @@ g_dbus_interface_info_ref (GDBusInterfaceInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -158,7 +158,7 @@ g_dbus_method_info_ref (GDBusMethodInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -178,7 +178,7 @@ g_dbus_signal_info_ref (GDBusSignalInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -198,7 +198,7 @@ g_dbus_property_info_ref (GDBusPropertyInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
@@ -218,7 +218,7 @@ g_dbus_arg_info_ref (GDBusArgInfo *info)
* If @info is statically allocated does nothing. Otherwise increases
* the reference count.
*
- * Returns: The same @info.
+ * Returns: (not nullable): The same @info.
*
* Since: 2.26
*/
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index bc9386ee7..cdc0b83e8 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -3204,7 +3204,7 @@ g_dbus_message_set_error_name (GDBusMessage *message,
const gchar *value)
{
g_return_if_fail (G_IS_DBUS_MESSAGE (message));
- g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
+ g_return_if_fail (value == NULL || g_dbus_is_error_name (value));
set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
}
@@ -3216,7 +3216,9 @@ g_dbus_message_set_error_name (GDBusMessage *message,
*
* Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
*
- * Returns: The value.
+ * This will always be non-%NULL, but may be an empty string.
+ *
+ * Returns: (not nullable): The value.
*
* Since: 2.26
*/
@@ -3488,7 +3490,7 @@ _sort_keys_func (gconstpointer a,
* fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
* ]|
*
- * Returns: A string that should be freed with g_free().
+ * Returns: (not nullable): A string that should be freed with g_free().
*
* Since: 2.26
*/
diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c
index 1130d6789..328354be4 100644
--- a/gio/gdbusnameowning.c
+++ b/gio/gdbusnameowning.c
@@ -39,7 +39,7 @@
* Convenience API for owning bus names.
*
* A simple example for owning a name can be found in
- * [gdbus-example-own-name.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-own-name.c)
+ * [gdbus-example-own-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-own-name.c)
*/
G_LOCK_DEFINE_STATIC (lock);
diff --git a/gio/gdbusnamewatching.c b/gio/gdbusnamewatching.c
index 8d24700c5..40aee5a3c 100644
--- a/gio/gdbusnamewatching.c
+++ b/gio/gdbusnamewatching.c
@@ -40,7 +40,7 @@
* Convenience API for watching bus names.
*
* A simple example for watching a name can be found in
- * [gdbus-example-watch-name.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-watch-name.c)
+ * [gdbus-example-watch-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-name.c)
*/
G_LOCK_DEFINE_STATIC (lock);
diff --git a/gio/gdbusobjectmanager.c b/gio/gdbusobjectmanager.c
index 87634cd83..169e7d16f 100644
--- a/gio/gdbusobjectmanager.c
+++ b/gio/gdbusobjectmanager.c
@@ -213,7 +213,7 @@ g_dbus_object_manager_get_objects (GDBusObjectManager *manager)
*
* Gets the #GDBusObjectProxy at @object_path, if any.
*
- * Returns: (transfer full): A #GDBusObject or %NULL. Free with
+ * Returns: (transfer full) (nullable): A #GDBusObject or %NULL. Free with
* g_object_unref().
*
* Since: 2.30
@@ -236,7 +236,7 @@ g_dbus_object_manager_get_object (GDBusObjectManager *manager,
* Gets the interface proxy for @interface_name at @object_path, if
* any.
*
- * Returns: (transfer full): A #GDBusInterface instance or %NULL. Free
+ * Returns: (transfer full) (nullable): A #GDBusInterface instance or %NULL. Free
* with g_object_unref().
*
* Since: 2.30
diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c
index 88fcff4fa..04c55995d 100644
--- a/gio/gdbusobjectmanagerclient.c
+++ b/gio/gdbusobjectmanagerclient.c
@@ -20,11 +20,13 @@
#include "config.h"
+#include "gcancellable.h"
#include "gdbusobjectmanager.h"
#include "gdbusobjectmanagerclient.h"
#include "gdbusobject.h"
#include "gdbusprivate.h"
#include "gioenumtypes.h"
+#include "gioerror.h"
#include "ginitable.h"
#include "gasyncresult.h"
#include "gasyncinitable.h"
@@ -144,6 +146,7 @@ struct _GDBusObjectManagerClientPrivate
gulong name_owner_signal_id;
gulong signal_signal_id;
+ GCancellable *cancel;
};
enum
@@ -192,6 +195,20 @@ static void process_get_all_result (GDBusObjectManagerClient *manager,
const gchar *name_owner);
static void
+g_dbus_object_manager_client_dispose (GObject *object)
+{
+ GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object);
+
+ if (manager->priv->cancel != NULL)
+ {
+ g_cancellable_cancel (manager->priv->cancel);
+ g_clear_object (&manager->priv->cancel);
+ }
+
+ G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->dispose (object);
+}
+
+static void
g_dbus_object_manager_client_finalize (GObject *object)
{
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object);
@@ -327,6 +344,7 @@ g_dbus_object_manager_client_class_init (GDBusObjectManagerClientClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = g_dbus_object_manager_client_dispose;
gobject_class->finalize = g_dbus_object_manager_client_finalize;
gobject_class->set_property = g_dbus_object_manager_client_set_property;
gobject_class->get_property = g_dbus_object_manager_client_get_property;
@@ -589,6 +607,7 @@ g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager)
g_str_equal,
g_free,
(GDestroyNotify) g_object_unref);
+ manager->priv->cancel = g_cancellable_new ();
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1244,6 +1263,75 @@ maybe_unsubscribe_signals (GDBusObjectManagerClient *manager)
/* ---------------------------------------------------------------------------------------------------- */
+static GWeakRef *
+weak_ref_new (GObject *object)
+{
+ GWeakRef *weak_ref = g_new0 (GWeakRef, 1);
+ g_weak_ref_init (weak_ref, object);
+ return g_steal_pointer (&weak_ref);
+}
+
+static void
+weak_ref_free (GWeakRef *weak_ref)
+{
+ g_weak_ref_clear (weak_ref);
+ g_free (weak_ref);
+}
+
+static void
+on_get_managed_objects_finish (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+
+ GDBusProxy *proxy = G_DBUS_PROXY (source);
+ GWeakRef *manager_weak = user_data;
+ GDBusObjectManagerClient *manager;
+ GError *error = NULL;
+ GVariant *value = NULL;
+ gchar *new_name_owner = NULL;
+
+ value = g_dbus_proxy_call_finish (proxy, result, &error);
+
+ manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak));
+ /* Manager got disposed, nothing to do */
+ if (manager == NULL)
+ {
+ goto out;
+ }
+
+ new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
+ if (value == NULL)
+ {
+ maybe_unsubscribe_signals (manager);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s",
+ new_name_owner,
+ manager->priv->name,
+ error->message);
+ }
+ }
+ else
+ {
+ process_get_all_result (manager, value, new_name_owner);
+ }
+
+ /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
+ * way the user knows that the signals were emitted because the name owner came back
+ */
+ g_mutex_lock (&manager->priv->lock);
+ manager->priv->name_owner = g_steal_pointer (&new_name_owner);
+ g_mutex_unlock (&manager->priv->lock);
+ g_object_notify (G_OBJECT (manager), "name-owner");
+
+ g_object_unref (manager);
+ out:
+ g_clear_error (&error);
+ g_clear_pointer (&value, g_variant_unref);
+ weak_ref_free (manager_weak);
+}
+
static void
on_notify_g_name_owner (GObject *object,
GParamSpec *pspec,
@@ -1298,65 +1386,24 @@ on_notify_g_name_owner (GObject *object,
if (new_name_owner != NULL)
{
- GError *error;
- GVariant *value;
-
//g_debug ("repopulating for %s", new_name_owner);
- /* TODO: do this async! */
subscribe_signals (manager,
new_name_owner);
- error = NULL;
- value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
- "GetManagedObjects",
- NULL, /* parameters */
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (value == NULL)
- {
- maybe_unsubscribe_signals (manager);
- g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s",
- new_name_owner,
- manager->priv->name,
- error->message);
- g_error_free (error);
- }
- else
- {
- process_get_all_result (manager, value, new_name_owner);
- g_variant_unref (value);
- }
-
- /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
- * way the user knows that the signals were emitted because the name owner came back
- */
- g_mutex_lock (&manager->priv->lock);
- manager->priv->name_owner = new_name_owner;
- g_mutex_unlock (&manager->priv->lock);
- g_object_notify (G_OBJECT (manager), "name-owner");
-
+ g_dbus_proxy_call (manager->priv->control_proxy,
+ "GetManagedObjects",
+ NULL, /* parameters */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ manager->priv->cancel,
+ on_get_managed_objects_finish,
+ weak_ref_new (G_OBJECT (manager)));
}
+ g_free (new_name_owner);
g_free (old_name_owner);
g_object_unref (manager);
}
-static GWeakRef *
-weak_ref_new (GObject *object)
-{
- GWeakRef *weak_ref = g_new0 (GWeakRef, 1);
- g_weak_ref_init (weak_ref, object);
- return g_steal_pointer (&weak_ref);
-}
-
-static void
-weak_ref_free (GWeakRef *weak_ref)
-{
- g_weak_ref_clear (weak_ref);
- g_free (weak_ref);
-}
-
static gboolean
initable_init (GInitable *initable,
GCancellable *cancellable,
diff --git a/gio/gdbusobjectmanagerserver.c b/gio/gdbusobjectmanagerserver.c
index 39f4ed500..a68594765 100644
--- a/gio/gdbusobjectmanagerserver.c
+++ b/gio/gdbusobjectmanagerserver.c
@@ -318,7 +318,7 @@ g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
*
* Gets the #GDBusConnection used by @manager.
*
- * Returns: (transfer full): A #GDBusConnection object or %NULL if
+ * Returns: (transfer full) (nullable): A #GDBusConnection object or %NULL if
* @manager isn't exported on a connection. The returned object should
* be freed with g_object_unref().
*
@@ -565,12 +565,12 @@ void
g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
GDBusObjectSkeleton *object)
{
- gchar *orig_object_path;
+ const gchar *orig_object_path;
gchar *object_path;
guint count;
gboolean modified;
- orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ orig_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (G_IS_DBUS_OBJECT (object));
@@ -602,7 +602,6 @@ g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
g_free (object_path);
- g_free (orig_object_path);
}
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 282678f3b..7e62fa89e 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -2292,7 +2292,7 @@ turn_off_the_starting_cursor (void)
}
}
-__declspec(dllexport) void __stdcall
+void __stdcall
g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow)
{
GDBusDaemon *daemon;
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
index 8f8a93ba7..72d2c32a9 100644
--- a/gio/gdbusprivate.h
+++ b/gio/gdbusprivate.h
@@ -117,7 +117,7 @@ gchar *_g_dbus_win32_get_user_sid (void);
* Initially this function was introduces for usage with rundll,
* so the signature is kept rundll-compatible, though parameters aren't used.
*/
-__declspec(dllexport) void __stdcall
+_GLIB_EXTERN void __stdcall
g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow);
gchar *_g_dbus_win32_get_session_address_dbus_launch (GError **error);
#endif
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 45fa99a17..7a2289bd4 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -71,6 +71,13 @@
* the message bus launching an owner (unless
* %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is set).
*
+ * If the proxy is for a stateless D-Bus service, where the name owner may
+ * be started and stopped between calls, the #GDBusProxy:g-name-owner tracking
+ * of #GDBusProxy will cause the proxy to drop signal and property changes from
+ * the service after it has restarted for the first time. When interacting
+ * with a stateless D-Bus service, do not use #GDBusProxy — use direct D-Bus
+ * method calls and signal connections.
+ *
* The generic #GDBusProxy::g-properties-changed and
* #GDBusProxy::g-signal signals are not very convenient to work with.
* Therefore, the recommended way of working with proxies is to subclass
@@ -85,7 +92,7 @@
* of the thread where the instance was constructed.
*
* An example using a proxy for a well-known name can be found in
- * [gdbus-example-watch-proxy.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-watch-proxy.c)
+ * [gdbus-example-watch-proxy.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-proxy.c)
*/
/* lock protecting the mutable properties: name_owner, timeout_msec,
@@ -2239,7 +2246,7 @@ g_dbus_proxy_new_for_bus_sync (GBusType bus_type,
*
* Gets the connection @proxy is for.
*
- * Returns: (transfer none): A #GDBusConnection owned by @proxy. Do not free.
+ * Returns: (transfer none) (not nullable): A #GDBusConnection owned by @proxy. Do not free.
*
* Since: 2.26
*/
@@ -2273,7 +2280,11 @@ g_dbus_proxy_get_flags (GDBusProxy *proxy)
*
* Gets the name that @proxy was constructed for.
*
- * Returns: A string owned by @proxy. Do not free.
+ * When connected to a message bus, this will usually be non-%NULL.
+ * However, it may be %NULL for a proxy that communicates using a peer-to-peer
+ * pattern.
+ *
+ * Returns: (nullable): A string owned by @proxy. Do not free.
*
* Since: 2.26
*/
@@ -2317,7 +2328,7 @@ g_dbus_proxy_get_name_owner (GDBusProxy *proxy)
*
* Gets the object path @proxy is for.
*
- * Returns: A string owned by @proxy. Do not free.
+ * Returns: (not nullable): A string owned by @proxy. Do not free.
*
* Since: 2.26
*/
@@ -2334,7 +2345,7 @@ g_dbus_proxy_get_object_path (GDBusProxy *proxy)
*
* Gets the D-Bus interface name @proxy is for.
*
- * Returns: A string owned by @proxy. Do not free.
+ * Returns: (not nullable): A string owned by @proxy. Do not free.
*
* Since: 2.26
*/
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 3cf98587b..3fdded58a 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -77,7 +77,7 @@
* session or system bus, you should instead use g_bus_own_name().
*
* An example of peer-to-peer communication with GDBus can be found
- * in [gdbus-example-peer.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-peer.c).
+ * in [gdbus-example-peer.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-peer.c).
*
* Note that a minimal #GDBusServer will accept connections from any
* peer. In many use-cases it will be necessary to add a #GDBusAuthObserver
@@ -320,7 +320,9 @@ g_dbus_server_class_init (GDBusServerClass *klass)
/**
* GDBusServer:guid:
*
- * The guid of the server.
+ * The GUID of the server.
+ *
+ * See #GDBusConnection:guid for more details.
*
* Since: 2.26
*/
@@ -542,7 +544,9 @@ g_dbus_server_new_sync (const gchar *address,
* [D-Bus address](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses)
* string that can be used by clients to connect to @server.
*
- * Returns: A D-Bus address string. Do not free, the string is owned
+ * This is valid and non-empty if initializing the #GDBusServer succeeded.
+ *
+ * Returns: (not nullable): A D-Bus address string. Do not free, the string is owned
* by @server.
*
* Since: 2.26
@@ -558,9 +562,9 @@ g_dbus_server_get_client_address (GDBusServer *server)
* g_dbus_server_get_guid:
* @server: A #GDBusServer.
*
- * Gets the GUID for @server.
+ * Gets the GUID for @server, as provided to g_dbus_server_new_sync().
*
- * Returns: A D-Bus GUID. Do not free this string, it is owned by @server.
+ * Returns: (not nullable): A D-Bus GUID. Do not free this string, it is owned by @server.
*
* Since: 2.26
*/
diff --git a/gio/gdbusutils.c b/gio/gdbusutils.c
index bb34e2d58..f12e86204 100644
--- a/gio/gdbusutils.c
+++ b/gio/gdbusutils.c
@@ -268,6 +268,28 @@ g_dbus_is_interface_name (const gchar *string)
return ret;
}
+/**
+ * g_dbus_is_error_name:
+ * @string: The string to check.
+ *
+ * Check whether @string is a valid D-Bus error name.
+ *
+ * This function returns the same result as g_dbus_is_interface_name(),
+ * because D-Bus error names are defined to have exactly the
+ * same syntax as interface names.
+ *
+ * Returns: %TRUE if valid, %FALSE otherwise.
+ *
+ * Since: 2.70
+ */
+gboolean
+g_dbus_is_error_name (const gchar *string)
+{
+ /* Error names are the same syntax as interface names.
+ * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error */
+ return g_dbus_is_interface_name (string);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
/* TODO: maybe move to glib? if so, it should conform to http://en.wikipedia.org/wiki/Guid and/or
@@ -280,8 +302,14 @@ g_dbus_is_interface_name (const gchar *string)
* Generate a D-Bus GUID that can be used with
* e.g. g_dbus_connection_new().
*
- * See the D-Bus specification regarding what strings are valid D-Bus
- * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
+ * See the
+ * [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#uuids)
+ * regarding what strings are valid D-Bus GUIDs. The specification refers to
+ * these as ‘UUIDs’ whereas GLib (for historical reasons) refers to them as
+ * ‘GUIDs’. The terms are interchangeable.
+ *
+ * Note that D-Bus GUIDs do not follow
+ * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122).
*
* Returns: A valid D-Bus GUID. Free with g_free().
*
@@ -317,10 +345,10 @@ g_dbus_generate_guid (void)
*
* Checks if @string is a D-Bus GUID.
*
- * See the D-Bus specification regarding what strings are valid D-Bus
- * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
+ * See the documentation for g_dbus_generate_guid() for more information about
+ * the format of a GUID.
*
- * Returns: %TRUE if @string is a guid, %FALSE otherwise.
+ * Returns: %TRUE if @string is a GUID, %FALSE otherwise.
*
* Since: 2.26
*/
diff --git a/gio/gdbusutils.h b/gio/gdbusutils.h
index fd7358fcf..da8e42280 100644
--- a/gio/gdbusutils.h
+++ b/gio/gdbusutils.h
@@ -42,6 +42,8 @@ GLIB_AVAILABLE_IN_ALL
gboolean g_dbus_is_member_name (const gchar *string);
GLIB_AVAILABLE_IN_ALL
gboolean g_dbus_is_interface_name (const gchar *string);
+GLIB_AVAILABLE_IN_2_70
+gboolean g_dbus_is_error_name (const gchar *string);
GLIB_AVAILABLE_IN_ALL
void g_dbus_gvariant_to_gvalue (GVariant *value,
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 1a4b97918..63ef0c045 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -3734,7 +3734,7 @@ update_program_done (GPid pid,
gpointer data)
{
/* Did the application exit correctly */
- if (g_spawn_check_exit_status (status, NULL))
+ if (g_spawn_check_wait_status (status, NULL))
{
/* Here we could clean out any caches in use */
}
diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c
index 4bbc88d7a..880d87d2c 100644
--- a/gio/gdtlsconnection.c
+++ b/gio/gdtlsconnection.c
@@ -88,6 +88,8 @@ enum {
PROP_CERTIFICATE,
PROP_PEER_CERTIFICATE,
PROP_PEER_CERTIFICATE_ERRORS,
+ PROP_PROTOCOL_VERSION,
+ PROP_CIPHERSUITE_NAME,
};
static void
@@ -264,6 +266,37 @@ g_dtls_connection_default_init (GDtlsConnectionInterface *iface)
G_PARAM_STATIC_STRINGS));
/**
+ * GDtlsConnection:protocol-version:
+ *
+ * The DTLS protocol version in use. See g_dtls_connection_get_protocol_version().
+ *
+ * Since: 2.70
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_enum ("protocol-version",
+ P_("Protocol Version"),
+ P_("DTLS protocol version negotiated for this connection"),
+ G_TYPE_TLS_PROTOCOL_VERSION,
+ G_TLS_PROTOCOL_VERSION_UNKNOWN,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDtlsConnection:ciphersuite-name: (nullable)
+ *
+ * The name of the DTLS ciphersuite in use. See g_dtls_connection_get_ciphersuite_name().
+ *
+ * Since: 2.70
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("ciphersuite-name",
+ P_("Ciphersuite Name"),
+ P_("Name of ciphersuite negotiated for this connection"),
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* GDtlsConnection::accept-certificate:
* @conn: a #GDtlsConnection
* @peer_cert: the peer's #GTlsCertificate
@@ -1069,7 +1102,7 @@ g_dtls_connection_get_negotiated_protocol (GDtlsConnection *conn)
GDtlsConnectionInterface *iface;
iface = G_DTLS_CONNECTION_GET_INTERFACE (conn);
- if (iface->set_advertised_protocols == NULL)
+ if (iface->get_negotiated_protocol == NULL)
return NULL;
return iface->get_negotiated_protocol (conn);
@@ -1123,3 +1156,66 @@ g_dtls_connection_get_channel_binding_data (GDtlsConnection *conn,
return iface->get_binding_data (conn, type, data, error);
}
+
+/**
+ * g_dtls_connection_get_protocol_version:
+ * @conn: a #GDTlsConnection
+ *
+ * Returns the current DTLS protocol version, which may be
+ * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or
+ * has been closed, or if the TLS backend has implemented a protocol version
+ * that is not a recognized #GTlsProtocolVersion.
+ *
+ * Returns: The current DTLS protocol version
+ *
+ * Since: 2.70
+ */
+GTlsProtocolVersion
+g_dtls_connection_get_protocol_version (GDtlsConnection *conn)
+{
+ GTlsProtocolVersion protocol_version;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN);
+
+ g_object_get (G_OBJECT (conn),
+ "protocol-version", &protocol_version,
+ NULL);
+
+ /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */
+ enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION);
+ enum_value = g_enum_get_value (enum_class, protocol_version);
+ return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN;
+}
+
+/**
+ * g_dtls_connection_get_ciphersuite_name:
+ * @conn: a #GDTlsConnection
+ *
+ * Returns the name of the current DTLS ciphersuite, or %NULL if the
+ * connection has not handshaked or has been closed. Beware that the TLS
+ * backend may use any of multiple different naming conventions, because
+ * OpenSSL and GnuTLS have their own ciphersuite naming conventions that
+ * are different from each other and different from the standard, IANA-
+ * registered ciphersuite names. The ciphersuite name is intended to be
+ * displayed to the user for informative purposes only, and parsing it
+ * is not recommended.
+ *
+ * Returns: (nullable): The name of the current DTLS ciphersuite, or %NULL
+ *
+ * Since: 2.70
+ */
+gchar *
+g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn)
+{
+ gchar *ciphersuite_name;
+
+ g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL);
+
+ g_object_get (G_OBJECT (conn),
+ "ciphersuite-name", &ciphersuite_name,
+ NULL);
+
+ return g_steal_pointer (&ciphersuite_name);
+}
diff --git a/gio/gdtlsconnection.h b/gio/gdtlsconnection.h
index e73cf1459..8a5ca2723 100644
--- a/gio/gdtlsconnection.h
+++ b/gio/gdtlsconnection.h
@@ -45,8 +45,9 @@ typedef struct _GDtlsConnectionInterface GDtlsConnectionInterface;
* @shutdown: Shut down one or both directions of the connection.
* @shutdown_async: Start an asynchronous shutdown operation.
* @shutdown_finish: Finish an asynchronous shutdown operation.
- * @set_advertised_protocols: Set APLN protocol list
- * @get_negotiated_protocol: Retrieve ALPN-negotiated protocol
+ * @set_advertised_protocols: Set APLN protocol list (Since: 2.60)
+ * @get_negotiated_protocol: Get ALPN-negotiated protocol (Since: 2.60)
+ * @get_binding_data: Retrieve TLS channel binding data (Since: 2.66)
*
* Virtual method table for a #GDtlsConnection implementation.
*
@@ -216,6 +217,12 @@ gboolean g_dtls_connection_get_channel_binding_data (GDtlsConnec
GError **error);
G_GNUC_END_IGNORE_DEPRECATIONS
+GLIB_AVAILABLE_IN_2_70
+GTlsProtocolVersion g_dtls_connection_get_protocol_version (GDtlsConnection *conn);
+
+GLIB_AVAILABLE_IN_2_70
+gchar * g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn);
+
G_END_DECLS
#endif /* __G_DTLS_CONNECTION_H__ */
diff --git a/gio/gemblemedicon.c b/gio/gemblemedicon.c
index 42d013dfa..46fb95fbb 100644
--- a/gio/gemblemedicon.c
+++ b/gio/gemblemedicon.c
@@ -431,7 +431,7 @@ g_emblemed_icon_serialize (GIcon *icon)
icon_data = g_icon_serialize (node->data);
if (icon_data)
{
- /* We know how emblems serialise, so do a tweak here to
+ /* We know how emblems serialize, so do a tweak here to
* reduce some of the variant wrapping and redundant storage
* of 'emblem' over and again...
*/
diff --git a/gio/gfdonotificationbackend.c b/gio/gfdonotificationbackend.c
index b6fbfd2e2..4a0a557d6 100644
--- a/gio/gfdonotificationbackend.c
+++ b/gio/gfdonotificationbackend.c
@@ -257,6 +257,7 @@ call_notify (GDBusConnection *con,
GVariantBuilder hints_builder;
GIcon *icon;
GVariant *parameters;
+ const gchar *app_name;
const gchar *body;
guchar urgency;
@@ -322,10 +323,11 @@ call_notify (GDBusConnection *con,
}
}
+ app_name = g_get_application_name ();
body = g_notification_get_body (notification);
parameters = g_variant_new ("(susssasa{sv}i)",
- "", /* app name */
+ app_name ? app_name : "",
replace_id,
"", /* app icon */
g_notification_get_title (notification),
diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c
index ac2e4eb98..1f9bc24eb 100644
--- a/gio/gfileenumerator.c
+++ b/gio/gfileenumerator.c
@@ -787,7 +787,10 @@ next_files_thread (GTask *task,
}
if (error)
- g_task_return_error (task, error);
+ {
+ g_list_free_full (files, g_object_unref);
+ g_task_return_error (task, error);
+ }
else
g_task_return_pointer (task, files, (GDestroyNotify)next_async_op_free);
}
diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c
index 2a97758b2..a27c24626 100644
--- a/gio/gfileinfo.c
+++ b/gio/gfileinfo.c
@@ -46,6 +46,11 @@
* g_file_query_writable_namespaces() to discover the settable attributes
* of a particular file at runtime.
*
+ * The direct accessors, such as g_file_info_get_name(), are slightly more
+ * optimized than the generic attribute accessors, such as
+ * g_file_info_get_attribute_byte_string().This optimization will matter
+ * only if calling the API in a tight loop.
+ *
* #GFileAttributeMatcher allows for searching through a #GFileInfo for
* attributes.
**/
@@ -1835,6 +1840,96 @@ g_file_info_get_modification_date_time (GFileInfo *info)
}
/**
+ * g_file_info_get_access_date_time:
+ * @info: a #GFileInfo.
+ *
+ * Gets the access time of the current @info and returns it as a
+ * #GDateTime.
+ *
+ * This requires the %G_FILE_ATTRIBUTE_TIME_ACCESS attribute. If
+ * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is provided, the resulting #GDateTime
+ * will have microsecond precision.
+ *
+ * Returns: (transfer full) (nullable): access time, or %NULL if unknown
+ * Since: 2.70
+ */
+GDateTime *
+g_file_info_get_access_date_time (GFileInfo *info)
+{
+ static guint32 attr_atime = 0, attr_atime_usec;
+ GFileAttributeValue *value, *value_usec;
+ GDateTime *dt = NULL, *dt2 = NULL;
+
+ g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
+
+ if (attr_atime == 0)
+ {
+ attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
+ attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
+ }
+
+ value = g_file_info_find_value (info, attr_atime);
+ if (value == NULL)
+ return NULL;
+
+ dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
+
+ value_usec = g_file_info_find_value (info, attr_atime_usec);
+ if (value_usec == NULL)
+ return g_steal_pointer (&dt);
+
+ dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
+ g_date_time_unref (dt);
+
+ return g_steal_pointer (&dt2);
+}
+
+/**
+ * g_file_info_get_creation_date_time:
+ * @info: a #GFileInfo.
+ *
+ * Gets the creation time of the current @info and returns it as a
+ * #GDateTime.
+ *
+ * This requires the %G_FILE_ATTRIBUTE_TIME_CREATED attribute. If
+ * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is provided, the resulting #GDateTime
+ * will have microsecond precision.
+ *
+ * Returns: (transfer full) (nullable): creation time, or %NULL if unknown
+ * Since: 2.70
+ */
+GDateTime *
+g_file_info_get_creation_date_time (GFileInfo *info)
+{
+ static guint32 attr_ctime = 0, attr_ctime_usec;
+ GFileAttributeValue *value, *value_usec;
+ GDateTime *dt = NULL, *dt2 = NULL;
+
+ g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
+
+ if (attr_ctime == 0)
+ {
+ attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
+ attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
+ }
+
+ value = g_file_info_find_value (info, attr_ctime);
+ if (value == NULL)
+ return NULL;
+
+ dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
+
+ value_usec = g_file_info_find_value (info, attr_ctime_usec);
+ if (value_usec == NULL)
+ return g_steal_pointer (&dt);
+
+ dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
+ g_date_time_unref (dt);
+
+ return g_steal_pointer (&dt2);
+}
+
+/**
* g_file_info_get_symlink_target:
* @info: a #GFileInfo.
*
@@ -2238,6 +2333,76 @@ g_file_info_set_modification_date_time (GFileInfo *info,
}
/**
+ * g_file_info_set_access_date_time:
+ * @info: a #GFileInfo.
+ * @atime: (not nullable): a #GDateTime.
+ *
+ * Sets the %G_FILE_ATTRIBUTE_TIME_ACCESS and
+ * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC attributes in the file info to the
+ * given date/time value.
+ *
+ * Since: 2.70
+ */
+void
+g_file_info_set_access_date_time (GFileInfo *info,
+ GDateTime *atime)
+{
+ static guint32 attr_atime = 0, attr_atime_usec;
+ GFileAttributeValue *value;
+
+ g_return_if_fail (G_IS_FILE_INFO (info));
+ g_return_if_fail (atime != NULL);
+
+ if (attr_atime == 0)
+ {
+ attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
+ attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
+ }
+
+ value = g_file_info_create_value (info, attr_atime);
+ if (value)
+ _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (atime));
+ value = g_file_info_create_value (info, attr_atime_usec);
+ if (value)
+ _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (atime));
+}
+
+/**
+ * g_file_info_set_creation_date_time:
+ * @info: a #GFileInfo.
+ * @creation_time: (not nullable): a #GDateTime.
+ *
+ * Sets the %G_FILE_ATTRIBUTE_TIME_CREATED and
+ * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC attributes in the file info to the
+ * given date/time value.
+ *
+ * Since: 2.70
+ */
+void
+g_file_info_set_creation_date_time (GFileInfo *info,
+ GDateTime *creation_time)
+{
+ static guint32 attr_ctime = 0, attr_ctime_usec;
+ GFileAttributeValue *value;
+
+ g_return_if_fail (G_IS_FILE_INFO (info));
+ g_return_if_fail (creation_time != NULL);
+
+ if (attr_ctime == 0)
+ {
+ attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
+ attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
+ }
+
+ value = g_file_info_create_value (info, attr_ctime);
+ if (value)
+ _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (creation_time));
+ value = g_file_info_create_value (info, attr_ctime_usec);
+ if (value)
+ _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (creation_time));
+}
+
+/**
* g_file_info_set_symlink_target:
* @info: a #GFileInfo.
* @symlink_target: a static string containing a path to a symlink target.
diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h
index da202e6a7..4f736e487 100644
--- a/gio/gfileinfo.h
+++ b/gio/gfileinfo.h
@@ -1057,6 +1057,10 @@ void g_file_info_get_modification_time (GFileInfo *info,
G_GNUC_END_IGNORE_DEPRECATIONS
GLIB_AVAILABLE_IN_2_62
GDateTime * g_file_info_get_modification_date_time (GFileInfo *info);
+GLIB_AVAILABLE_IN_2_70
+GDateTime * g_file_info_get_access_date_time (GFileInfo *info);
+GLIB_AVAILABLE_IN_2_70
+GDateTime * g_file_info_get_creation_date_time (GFileInfo *info);
GLIB_AVAILABLE_IN_ALL
const char * g_file_info_get_symlink_target (GFileInfo *info);
GLIB_AVAILABLE_IN_ALL
@@ -1109,6 +1113,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
GLIB_AVAILABLE_IN_2_62
void g_file_info_set_modification_date_time (GFileInfo *info,
GDateTime *mtime);
+GLIB_AVAILABLE_IN_2_70
+void g_file_info_set_access_date_time (GFileInfo *info,
+ GDateTime *atime);
+GLIB_AVAILABLE_IN_2_70
+void g_file_info_set_creation_date_time (GFileInfo *info,
+ GDateTime *creation_time);
GLIB_AVAILABLE_IN_ALL
void g_file_info_set_symlink_target (GFileInfo *info,
const char *symlink_target);
diff --git a/gio/ginputstream.c b/gio/ginputstream.c
index 383495162..a40c7d9c4 100644
--- a/gio/ginputstream.c
+++ b/gio/ginputstream.c
@@ -129,7 +129,7 @@ g_input_stream_init (GInputStream *stream)
* @stream: a #GInputStream.
* @buffer: (array length=count) (element-type guint8) (out caller-allocates):
* a buffer to read data into (which should be at least count bytes long).
- * @count: the number of bytes that will be read from the stream
+ * @count: (in): the number of bytes that will be read from the stream
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
* @error: location to store the error occurring, or %NULL to ignore
*
@@ -210,7 +210,7 @@ g_input_stream_read (GInputStream *stream,
* @stream: a #GInputStream.
* @buffer: (array length=count) (element-type guint8) (out caller-allocates):
* a buffer to read data into (which should be at least count bytes long).
- * @count: the number of bytes that will be read from the stream
+ * @count: (in): the number of bytes that will be read from the stream
* @bytes_read: (out): location to store the number of bytes that was read from the stream
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
* @error: location to store the error occurring, or %NULL to ignore
@@ -427,8 +427,10 @@ g_input_stream_real_skip (GInputStream *stream,
NULL))
{
end = g_seekable_tell (seekable);
+ g_assert (start >= 0);
g_assert (end >= start);
- if (start > G_MAXSIZE - count || start + count > end)
+ if ((guint64) start > (G_MAXSIZE - count) ||
+ (start + count) > (guint64) end)
{
stream->priv->pending = TRUE;
return end - start;
@@ -581,7 +583,7 @@ async_ready_close_callback_wrapper (GObject *source_object,
* @stream: A #GInputStream.
* @buffer: (array length=count) (element-type guint8) (out caller-allocates):
* a buffer to read data into (which should be at least count bytes long).
- * @count: the number of bytes that will be read from the stream
+ * @count: (in): the number of bytes that will be read from the stream
* @io_priority: the [I/O priority][io-priority]
* of the request.
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
@@ -773,7 +775,7 @@ read_all_async_thread (GTask *task,
* @stream: A #GInputStream
* @buffer: (array length=count) (element-type guint8) (out caller-allocates):
* a buffer to read data into (which should be at least count bytes long)
- * @count: the number of bytes that will be read from the stream
+ * @count: (in): the number of bytes that will be read from the stream
* @io_priority: the [I/O priority][io-priority] of the request
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
* @callback: (scope async): callback to call when the request is satisfied
diff --git a/gio/gio-tool-cat.c b/gio/gio-tool-cat.c
index 66841dd3e..bb0c928f5 100644
--- a/gio/gio-tool-cat.c
+++ b/gio/gio-tool-cat.c
@@ -39,7 +39,7 @@
static const GOptionEntry entries[] = {
- { NULL }
+ G_OPTION_ENTRY_NULL
};
/* 256k minus malloc overhead */
diff --git a/gio/gio-tool-copy.c b/gio/gio-tool-copy.c
index 0083eba08..cbae0dc6c 100644
--- a/gio/gio-tool-copy.c
+++ b/gio/gio-tool-copy.c
@@ -47,7 +47,7 @@ static const GOptionEntry entries[] = {
{ "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, N_("Backup existing destination files"), NULL },
{ "no-dereference", 'P', 0, G_OPTION_ARG_NONE, &no_dereference, N_("Never follow symbolic links"), NULL },
{ "default-permissions", 0, 0, G_OPTION_ARG_NONE, &default_permissions, N_("Use default permissions for the destination"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gint64 start_time;
diff --git a/gio/gio-tool-info.c b/gio/gio-tool-info.c
index a06263545..336da64e2 100644
--- a/gio/gio-tool-info.c
+++ b/gio/gio-tool-info.c
@@ -38,7 +38,7 @@ static const GOptionEntry entries[] = {
{ "filesystem", 'f', 0, G_OPTION_ARG_NONE, &filesystem, N_("Get file system info"), NULL },
{ "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, N_("The attributes to get"), N_("ATTRIBUTES") },
{ "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static char *
diff --git a/gio/gio-tool-launch.c b/gio/gio-tool-launch.c
index 08c91c68a..edc2cf226 100644
--- a/gio/gio-tool-launch.c
+++ b/gio/gio-tool-launch.c
@@ -30,7 +30,7 @@
#include "gio-tool.h"
static const GOptionEntry entries[] = {
- { NULL }
+ G_OPTION_ENTRY_NULL
};
int
diff --git a/gio/gio-tool-list.c b/gio/gio-tool-list.c
index 9f52d158d..8e9409f10 100644
--- a/gio/gio-tool-list.c
+++ b/gio/gio-tool-list.c
@@ -39,7 +39,7 @@ static const GOptionEntry entries[] = {
{ "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL},
{ "print-display-names", 'd', 0, G_OPTION_ARG_NONE, &print_display_names, N_("Print display names"), NULL },
{ "print-uris", 'u', 0, G_OPTION_ARG_NONE, &print_uris, N_("Print full URIs"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/gio-tool-mime.c b/gio/gio-tool-mime.c
index f564b1fd9..be8a4a9bd 100644
--- a/gio/gio-tool-mime.c
+++ b/gio/gio-tool-mime.c
@@ -30,7 +30,7 @@
#include "gio-tool.h"
static const GOptionEntry entries[] = {
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static GAppInfo *
diff --git a/gio/gio-tool-mkdir.c b/gio/gio-tool-mkdir.c
index 66bf85894..49cb0c328 100644
--- a/gio/gio-tool-mkdir.c
+++ b/gio/gio-tool-mkdir.c
@@ -29,7 +29,7 @@ static gboolean parent = FALSE;
static const GOptionEntry entries[] = {
{ "parent", 'p', 0, G_OPTION_ARG_NONE, &parent, N_("Create parent directories"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
int
diff --git a/gio/gio-tool-monitor.c b/gio/gio-tool-monitor.c
index 73ee1b12e..9eacfbf69 100644
--- a/gio/gio-tool-monitor.c
+++ b/gio/gio-tool-monitor.c
@@ -47,7 +47,7 @@ static const GOptionEntry entries[] = {
N_("Watch for mount events"), NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_default,
NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/gio-tool-mount.c b/gio/gio-tool-mount.c
index 67278bb5c..c62426828 100644
--- a/gio/gio-tool-mount.c
+++ b/gio/gio-tool-mount.c
@@ -75,7 +75,7 @@ static const GOptionEntry entries[] =
{ "tcrypt-pim", 0, 0, G_OPTION_ARG_INT, &tcrypt_pim, N_("The numeric PIM when unlocking a VeraCrypt volume"), N_("PIM")},
{ "tcrypt-hidden", 0, 0, G_OPTION_ARG_NONE, &tcrypt_hidden, N_("Mount a TCRYPT hidden volume"), NULL},
{ "tcrypt-system", 0, 0, G_OPTION_ARG_NONE, &tcrypt_system, N_("Mount a TCRYPT system volume"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static char *
diff --git a/gio/gio-tool-move.c b/gio/gio-tool-move.c
index 5755f59d4..9be51bcd8 100644
--- a/gio/gio-tool-move.c
+++ b/gio/gio-tool-move.c
@@ -40,7 +40,7 @@ static const GOptionEntry entries[] = {
{ "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive, N_("Prompt before overwrite"), NULL },
{ "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, N_("Backup existing destination files"), NULL },
{ "no-copy-fallback", 'C', 0, G_OPTION_ARG_NONE, &no_copy_fallback, N_("Don’t use copy and delete fallback"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gint64 start_time;
diff --git a/gio/gio-tool-open.c b/gio/gio-tool-open.c
index ac6764a97..f55057bd2 100644
--- a/gio/gio-tool-open.c
+++ b/gio/gio-tool-open.c
@@ -33,7 +33,7 @@ static int n_outstanding = 0;
static gboolean success = TRUE;
static const GOptionEntry entries[] = {
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/gio-tool-remove.c b/gio/gio-tool-remove.c
index 8748b4629..fb995bfff 100644
--- a/gio/gio-tool-remove.c
+++ b/gio/gio-tool-remove.c
@@ -29,7 +29,7 @@ static gboolean force = FALSE;
static const GOptionEntry entries[] = {
{"force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore nonexistent files, never prompt"), NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
int
diff --git a/gio/gio-tool-rename.c b/gio/gio-tool-rename.c
index 36e4a8e20..0070b6c60 100644
--- a/gio/gio-tool-rename.c
+++ b/gio/gio-tool-rename.c
@@ -26,7 +26,7 @@
static const GOptionEntry entries[] = {
- { NULL }
+ G_OPTION_ENTRY_NULL
};
int
diff --git a/gio/gio-tool-save.c b/gio/gio-tool-save.c
index 4969b8b9d..30fb3f91e 100644
--- a/gio/gio-tool-save.c
+++ b/gio/gio-tool-save.c
@@ -55,7 +55,7 @@ static const GOptionEntry entries[] =
{ "print-etag", 'v', 0, G_OPTION_ARG_NONE, &print_etag, N_("Print new etag at end"), NULL },
/* Translators: The "etag" is a token allowing to verify whether a file has been modified */
{ "etag", 'e', 0, G_OPTION_ARG_STRING, &etag, N_("The etag of the file being overwritten"), N_("ETAG") },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
/* 256k minus malloc overhead */
diff --git a/gio/gio-tool-set.c b/gio/gio-tool-set.c
index ab3ac1544..4dbe1214f 100644
--- a/gio/gio-tool-set.c
+++ b/gio/gio-tool-set.c
@@ -32,7 +32,7 @@ static gboolean nofollow_symlinks = FALSE;
static const GOptionEntry entries[] = {
{ "type", 't', 0, G_OPTION_ARG_STRING, &attr_type, N_("Type of the attribute"), N_("TYPE") },
{ "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static char *
diff --git a/gio/gio-tool-trash.c b/gio/gio-tool-trash.c
index fc17b4cba..449fa9577 100644
--- a/gio/gio-tool-trash.c
+++ b/gio/gio-tool-trash.c
@@ -35,7 +35,7 @@ static const GOptionEntry entries[] = {
{ "list", 0, 0, G_OPTION_ARG_NONE, &list, N_("List files in the trash with their original locations"), NULL },
{ "restore", 0, 0, G_OPTION_ARG_NONE, &restore, N_("Restore a file from trash to its original location (possibly "
"recreating the directory)"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/gio-tool-tree.c b/gio/gio-tool-tree.c
index 2327c4549..c572afc37 100644
--- a/gio/gio-tool-tree.c
+++ b/gio/gio-tool-tree.c
@@ -31,7 +31,7 @@ static gboolean follow_symlinks = FALSE;
static const GOptionEntry entries[] = {
{ "hidden", 'h', 0, G_OPTION_ARG_NONE, &show_hidden, N_("Show hidden files"), NULL },
{ "follow-symlinks", 'l', 0, G_OPTION_ARG_NONE, &follow_symlinks, N_("Follow symbolic links, mounts and shortcuts"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static gint
diff --git a/gio/gioenums.h b/gio/gioenums.h
index f2f66c875..d81ada416 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1703,6 +1703,12 @@ typedef enum {
* wrong many times, and the user may not have many chances left.
* @G_TLS_PASSWORD_FINAL_TRY: Hint to the user that this is the last try to get
* this password right.
+ * @G_TLS_PASSWORD_PKCS11_USER: For PKCS #11, the user PIN is required.
+ * Since: 2.70.
+ * @G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER: For PKCS #11, the security officer
+ * PIN is required. Since: 2.70.
+ * @G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC: For PKCS #11, the context-specific
+ * PIN is required. Since: 2.70.
*
* Various flags for the password.
*
@@ -1714,7 +1720,10 @@ typedef enum _GTlsPasswordFlags
G_TLS_PASSWORD_NONE = 0,
G_TLS_PASSWORD_RETRY = 1 << 1,
G_TLS_PASSWORD_MANY_TRIES = 1 << 2,
- G_TLS_PASSWORD_FINAL_TRY = 1 << 3
+ G_TLS_PASSWORD_FINAL_TRY = 1 << 3,
+ G_TLS_PASSWORD_PKCS11_USER = 1 << 4,
+ G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER = 1 << 5,
+ G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC = 1 << 6
} GTlsPasswordFlags;
/**
@@ -1817,6 +1826,40 @@ typedef enum {
} GTlsCertificateRequestFlags;
/**
+ * GTlsProtocolVersion:
+ * @G_TLS_PROTOCOL_VERSION_UNKNOWN: No protocol version or unknown protocol version
+ * @G_TLS_PROTOCOL_VERSION_SSL_3_0: SSL 3.0, which is insecure and should not be used
+ * @G_TLS_PROTOCOL_VERSION_TLS_1_0: TLS 1.0, which is insecure and should not be used
+ * @G_TLS_PROTOCOL_VERSION_TLS_1_1: TLS 1.1, which is insecure and should not be used
+ * @G_TLS_PROTOCOL_VERSION_TLS_1_2: TLS 1.2, defined by [RFC 5246](https://datatracker.ietf.org/doc/html/rfc5246)
+ * @G_TLS_PROTOCOL_VERSION_TLS_1_3: TLS 1.3, defined by [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446)
+ * @G_TLS_PROTOCOL_VERSION_DTLS_1_0: DTLS 1.0, which is insecure and should not be used
+ * @G_TLS_PROTOCOL_VERSION_DTLS_1_2: DTLS 1.2, defined by [RFC 6347](https://datatracker.ietf.org/doc/html/rfc6347)
+ *
+ * The TLS or DTLS protocol version used by a #GTlsConnection or
+ * #GDtlsConnection. The integer values of these versions are sequential
+ * to ensure newer known protocol versions compare greater than older
+ * known versions. Any known DTLS protocol version will compare greater
+ * than any SSL or TLS protocol version. The protocol version may be
+ * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the TLS backend supports a newer
+ * protocol version that GLib does not yet know about. This means that
+ * it's possible for an unknown DTLS protocol version to compare less
+ * than the TLS protocol versions.
+ *
+ * Since: 2.70
+ */
+typedef enum {
+ G_TLS_PROTOCOL_VERSION_UNKNOWN = 0,
+ G_TLS_PROTOCOL_VERSION_SSL_3_0 = 1,
+ G_TLS_PROTOCOL_VERSION_TLS_1_0 = 2,
+ G_TLS_PROTOCOL_VERSION_TLS_1_1 = 3,
+ G_TLS_PROTOCOL_VERSION_TLS_1_2 = 4,
+ G_TLS_PROTOCOL_VERSION_TLS_1_3 = 5,
+ G_TLS_PROTOCOL_VERSION_DTLS_1_0 = 201,
+ G_TLS_PROTOCOL_VERSION_DTLS_1_2 = 202,
+} GTlsProtocolVersion;
+
+/**
* GIOModuleScopeFlags:
* @G_IO_MODULE_SCOPE_NONE: No module scan flags
* @G_IO_MODULE_SCOPE_BLOCK_DUPLICATES: When using this scope to load or
diff --git a/gio/giomodule.c b/gio/giomodule.c
index a2909a8ef..d3b5e482a 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -731,7 +731,7 @@ print_help (const char *envvar,
{
GList *l;
GIOExtension *extension;
- int width = 0;
+ gsize width = 0;
for (l = g_io_extension_point_get_extensions (ep); l; l = l->next)
{
@@ -743,7 +743,9 @@ print_help (const char *envvar,
{
extension = l->data;
- g_print (" %*s - %d\n", width, g_io_extension_get_name (extension), g_io_extension_get_priority (extension));
+ g_print (" %*s - %d\n", (int) MIN (width, G_MAXINT),
+ g_io_extension_get_name (extension),
+ g_io_extension_get_priority (extension));
}
}
}
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index 094be3f91..9319491d5 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -66,9 +66,9 @@ typedef struct
GHashTable *system_locks; /* Used as a set, owning the strings it contains */
gchar *prefix;
- gint prefix_len;
+ gsize prefix_len;
gchar *root_group;
- gint root_group_len;
+ gsize root_group_len;
GFile *file;
GFileMonitor *file_monitor;
@@ -173,7 +173,9 @@ convert_path (GKeyfileSettingsBackend *kfsb,
/* if a root_group was specified, make sure the user hasn't given
* a path that ghosts that group name
*/
- if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0)
+ if (last_slash != NULL && last_slash - key >= 0 &&
+ (gsize) (last_slash - key) == kfsb->root_group_len &&
+ memcmp (key, kfsb->root_group, last_slash - key) == 0)
return FALSE;
}
else
diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c
index 74373e5b0..db621a7b6 100644
--- a/gio/glib-compile-resources.c
+++ b/gio/glib-compile-resources.c
@@ -747,7 +747,7 @@ main (int argc, char **argv)
{ "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don’t export functions; declare them G_GNUC_INTERNAL"), NULL },
{ "external-data", 0, 0, G_OPTION_ARG_NONE, &external_data, N_("Don’t embed resource data in the C file; assume it's linked externally instead"), NULL },
{ "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
#ifdef G_OS_WIN32
diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c
index cfea042f8..7e1152f6b 100644
--- a/gio/glib-compile-schemas.c
+++ b/gio/glib-compile-schemas.c
@@ -2178,7 +2178,7 @@ main (int argc, char **argv)
/* These options are only for use in the gschema-compile tests */
{ "schema-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &schema_files, NULL, NULL },
{ "override-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &override_files, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
#ifdef G_OS_WIN32
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 51a94e51c..873aa911f 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -609,6 +609,8 @@ get_fs_type (long f_type)
return "efivarfs";
case 0x00414A53:
return "efs";
+ case 0x2011BAB0UL:
+ return "exfat";
case 0x137D:
return "ext";
case 0xEF51:
@@ -2068,7 +2070,6 @@ g_local_file_trash (GFile *file,
(global_stat.st_mode & S_ISVTX) != 0)
{
trashdir = g_build_filename (globaldir, uid_str, NULL);
- success = TRUE;
if (g_lstat (trashdir, &trash_stat) == 0)
{
@@ -2078,14 +2079,12 @@ g_local_file_trash (GFile *file,
/* Not a directory or not owned by user, ignore */
g_free (trashdir);
trashdir = NULL;
- success = FALSE;
}
}
else if (g_mkdir (trashdir, 0700) == -1)
{
g_free (trashdir);
trashdir = NULL;
- success = FALSE;
}
}
g_free (globaldir);
diff --git a/gio/gnotification.c b/gio/gnotification.c
index 27efed3f4..aa7df7f7b 100644
--- a/gio/gnotification.c
+++ b/gio/gnotification.c
@@ -43,6 +43,29 @@
* not running, applications using #GNotification should be able to be
* started as a D-Bus service, using #GApplication.
*
+ * In order for #GNotification to work, the application must have installed
+ * a `.desktop` file. For example:
+ * |[
+ * [Desktop Entry]
+ * Name=Test Application
+ * Comment=Description of what Test Application does
+ * Exec=gnome-test-application
+ * Icon=org.gnome.TestApplication
+ * Terminal=false
+ * Type=Application
+ * Categories=GNOME;GTK;TestApplication Category;
+ * StartupNotify=true
+ * DBusActivatable=true
+ * X-GNOME-UsesNotifications=true
+ * ]|
+ *
+ * The `X-GNOME-UsesNotifications` key indicates to GNOME Control Center
+ * that this application uses notifications, so it can be listed in the
+ * Control Center’s ‘Notifications’ panel.
+ *
+ * The `.desktop` file must be named as `org.gnome.TestApplication.desktop`,
+ * where `org.gnome.TestApplication` is the ID passed to g_application_new().
+ *
* User interaction with a notification (either the default action, or
* buttons) must be associated with actions on the application (ie:
* "app." actions). It is not possible to route user interaction
diff --git a/gio/gpollableinputstream.c b/gio/gpollableinputstream.c
index 6a13f34b6..d04019339 100644
--- a/gio/gpollableinputstream.c
+++ b/gio/gpollableinputstream.c
@@ -159,9 +159,9 @@ g_pollable_input_stream_default_read_nonblocking (GPollableInputStream *stream,
/**
* g_pollable_input_stream_read_nonblocking:
* @stream: a #GPollableInputStream
- * @buffer: (array length=count) (element-type guint8): a buffer to
- * read data into (which should be at least @count bytes long).
- * @count: the number of bytes you want to read
+ * @buffer: (array length=count) (element-type guint8) (out caller-allocates): a
+ * buffer to read data into (which should be at least @count bytes long).
+ * @count: (in): the number of bytes you want to read
* @cancellable: (nullable): a #GCancellable, or %NULL
* @error: #GError for error reporting, or %NULL to ignore.
*
diff --git a/gio/gresource-tool.c b/gio/gresource-tool.c
index 1914c5228..aa718974e 100644
--- a/gio/gresource-tool.c
+++ b/gio/gresource-tool.c
@@ -180,17 +180,18 @@ elf_foreach_resource_section (Elf *elf,
SectionCallback callback,
gpointer data)
{
+ int ret;
size_t shstrndx, shnum;
size_t scnidx;
Elf_Scn *scn;
GElf_Shdr *shdr, shdr_mem;
const gchar *section_name;
- elf_getshdrstrndx (elf, &shstrndx);
- g_assert (shstrndx >= 0);
+ ret = elf_getshdrstrndx (elf, &shstrndx);
+ g_assert (ret == 0);
- elf_getshdrnum (elf, &shnum);
- g_assert (shnum >= 0);
+ ret = elf_getshdrnum (elf, &shnum);
+ g_assert (ret == 0);
for (scnidx = 1; scnidx < shnum; scnidx++)
{
diff --git a/gio/gseekable.c b/gio/gseekable.c
index 28e815703..9689a77b6 100644
--- a/gio/gseekable.c
+++ b/gio/gseekable.c
@@ -59,7 +59,8 @@ g_seekable_default_init (GSeekableInterface *iface)
*
* Tells the current position within the stream.
*
- * Returns: the offset from the beginning of the buffer.
+ * Returns: the (positive or zero) offset from the beginning of the
+ * buffer, zero if the target is not seekable.
**/
goffset
g_seekable_tell (GSeekable *seekable)
diff --git a/gio/gsettings-tool.c b/gio/gsettings-tool.c
index 3096f9d9b..7559a6b1b 100644
--- a/gio/gsettings-tool.c
+++ b/gio/gsettings-tool.c
@@ -191,13 +191,16 @@ static void
gsettings_list_children (void)
{
gchar **children;
- gint max = 0;
+ gsize max = 0;
gint i;
children = g_settings_list_children (global_settings);
for (i = 0; children[i]; i++)
- if (strlen (children[i]) > max)
- max = strlen (children[i]);
+ {
+ gsize len = strlen (children[i]);
+ if (len > max)
+ max = len;
+ }
for (i = 0; children[i]; i++)
{
@@ -212,9 +215,11 @@ gsettings_list_children (void)
NULL);
if (g_settings_schema_get_path (schema) != NULL)
- g_print ("%-*s %s\n", max, children[i], g_settings_schema_get_id (schema));
+ g_print ("%-*s %s\n", (int) MIN (max, G_MAXINT), children[i],
+ g_settings_schema_get_id (schema));
else
- g_print ("%-*s %s:%s\n", max, children[i], g_settings_schema_get_id (schema), path);
+ g_print ("%-*s %s:%s\n", (int) MIN (max, G_MAXINT), children[i],
+ g_settings_schema_get_id (schema), path);
g_object_unref (child);
g_settings_schema_unref (schema);
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 9a04a8630..f7d39c77e 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -121,7 +121,7 @@
* utility. The input is a schema description in an XML format.
*
* A DTD for the gschema XML format can be found here:
- * [gschema.dtd](https://git.gnome.org/browse/glib/tree/gio/gschema.dtd)
+ * [gschema.dtd](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/gschema.dtd)
*
* The [glib-compile-schemas][glib-compile-schemas] tool expects schema
* files to have the extension `.gschema.xml`.
@@ -2434,28 +2434,24 @@ GSettings *
g_settings_get_child (GSettings *settings,
const gchar *name)
{
- const gchar *child_schema;
+ GSettingsSchema *child_schema;
gchar *child_path;
- gchar *child_name;
GSettings *child;
g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
- child_name = g_strconcat (name, "/", NULL);
- child_schema = g_settings_schema_get_string (settings->priv->schema,
- child_name);
+ child_schema = g_settings_schema_get_child_schema (settings->priv->schema,
+ name);
if (child_schema == NULL)
- g_error ("Schema '%s' has no child '%s'",
+ g_error ("Schema '%s' has no child '%s' or child schema not found",
g_settings_schema_get_id (settings->priv->schema), name);
- child_path = g_strconcat (settings->priv->path, child_name, NULL);
- child = g_object_new (G_TYPE_SETTINGS,
- "backend", settings->priv->backend,
- "schema-id", child_schema,
- "path", child_path,
- NULL);
+ child_path = g_strconcat (settings->priv->path, name, "/", NULL);
+ child = g_settings_new_full (child_schema,
+ settings->priv->backend,
+ child_path);
+ g_settings_schema_unref (child_schema);
g_free (child_path);
- g_free (child_name);
return child;
}
diff --git a/gio/gsettingsschema-internal.h b/gio/gsettingsschema-internal.h
index 5f996b4bc..416cf2d8c 100644
--- a/gio/gsettingsschema-internal.h
+++ b/gio/gsettingsschema-internal.h
@@ -50,6 +50,9 @@ const GQuark * g_settings_schema_list (GSettin
const gchar * g_settings_schema_get_string (GSettingsSchema *schema,
const gchar *key);
+GSettingsSchema * g_settings_schema_get_child_schema (GSettingsSchema *schema,
+ const gchar *name);
+
void g_settings_schema_key_init (GSettingsSchemaKey *key,
GSettingsSchema *schema,
const gchar *name);
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index a46d5056f..ec0caf655 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -968,6 +968,24 @@ g_settings_schema_get_string (GSettingsSchema *schema,
return result;
}
+GSettingsSchema *
+g_settings_schema_get_child_schema (GSettingsSchema *schema,
+ const gchar *name)
+{
+ const gchar *child_id;
+ gchar *child_name;
+
+ child_name = g_strconcat (name, "/", NULL);
+ child_id = g_settings_schema_get_string (schema, child_name);
+
+ g_free (child_name);
+
+ if (child_id == NULL)
+ return NULL;
+
+ return g_settings_schema_source_lookup (schema->source, child_id, TRUE);
+}
+
GVariantIter *
g_settings_schema_get_value (GSettingsSchema *schema,
const gchar *key)
diff --git a/gio/gsocket.c b/gio/gsocket.c
index f39a568b3..a7ba27d0c 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -4795,9 +4795,7 @@ g_socket_send_message (GSocket *socket,
if (num_vectors != -1)
{
- gint i;
-
- for (i = 0; i < num_vectors; i++)
+ for (gint i = 0; i < num_vectors; i++)
{
/* No wrap-around for vectors_size */
if (vectors_size > vectors_size + vectors[i].size)
@@ -4813,9 +4811,7 @@ g_socket_send_message (GSocket *socket,
}
else
{
- gsize i;
-
- for (i = 0; vectors[i].buffer != NULL; i++)
+ for (gsize i = 0; vectors[i].buffer != NULL; i++)
{
/* No wrap-around for vectors_size */
if (vectors_size > vectors_size + vectors[i].size)
diff --git a/gio/gsocketcontrolmessage.c b/gio/gsocketcontrolmessage.c
index 255610c46..198ddeca3 100644
--- a/gio/gsocketcontrolmessage.c
+++ b/gio/gsocketcontrolmessage.c
@@ -204,7 +204,7 @@ g_socket_control_message_deserialize (int level,
* example, the control message may be be discarded if it is deemed
* empty, see e.g.
*
- * http://git.gnome.org/browse/glib/commit/?id=ec91ed00f14c70cca9749347b8ebc19d72d9885b
+ * https://gitlab.gnome.org/GNOME/glib/commit/ec91ed00f14c70cca9749347b8ebc19d72d9885b
*
* Therefore, it's not appropriate to print a warning about not
* being able to deserialize the message.
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index bdf1608dc..9baa609bc 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -913,7 +913,7 @@ g_socket_listener_accept_socket_finish (GSocketListener *listener,
* This is the asynchronous version of g_socket_listener_accept().
*
* When the operation is finished @callback will be
- * called. You can then call g_socket_listener_accept_socket()
+ * called. You can then call g_socket_listener_accept_finish()
* to get the result of the operation.
*
* Since: 2.22
diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c
index 77a23efc3..c0f4f8db6 100644
--- a/gio/gsubprocess.c
+++ b/gio/gsubprocess.c
@@ -883,7 +883,7 @@ g_subprocess_wait (GSubprocess *subprocess,
* @cancellable: a #GCancellable
* @error: a #GError
*
- * Combines g_subprocess_wait() with g_spawn_check_exit_status().
+ * Combines g_subprocess_wait() with g_spawn_check_wait_status().
*
* Returns: %TRUE on success, %FALSE if process exited abnormally, or
* @cancellable was cancelled
@@ -896,7 +896,7 @@ g_subprocess_wait_check (GSubprocess *subprocess,
GError **error)
{
return g_subprocess_wait (subprocess, cancellable, error) &&
- g_spawn_check_exit_status (subprocess->status, error);
+ g_spawn_check_wait_status (subprocess->status, error);
}
/**
@@ -906,7 +906,7 @@ g_subprocess_wait_check (GSubprocess *subprocess,
* @callback: a #GAsyncReadyCallback to call when the operation is complete
* @user_data: user_data for @callback
*
- * Combines g_subprocess_wait_async() with g_spawn_check_exit_status().
+ * Combines g_subprocess_wait_async() with g_spawn_check_wait_status().
*
* This is the asynchronous version of g_subprocess_wait_check().
*
@@ -940,7 +940,7 @@ g_subprocess_wait_check_finish (GSubprocess *subprocess,
GError **error)
{
return g_subprocess_wait_finish (subprocess, result, error) &&
- g_spawn_check_exit_status (subprocess->status, error);
+ g_spawn_check_wait_status (subprocess->status, error);
}
#ifdef G_OS_UNIX
@@ -1053,7 +1053,7 @@ g_subprocess_force_exit (GSubprocess *subprocess)
*
* This value has no particular meaning, but it can be used with the
* macros defined by the system headers such as WIFEXITED. It can also
- * be used with g_spawn_check_exit_status().
+ * be used with g_spawn_check_wait_status().
*
* It is more likely that you want to use g_subprocess_get_if_exited()
* followed by g_subprocess_get_exit_status().
diff --git a/gio/gtask.c b/gio/gtask.c
index 2b4720de8..b533a18cf 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -1528,9 +1528,9 @@ g_task_start_task_thread (GTask *task,
*
* Although GLib currently rate-limits the tasks queued via
* g_task_run_in_thread(), you should not assume that it will always
- * do this. If you have a very large number of tasks to run, but don't
- * want them to all run at once, you should only queue a limited
- * number of them at a time.
+ * do this. If you have a very large number of tasks to run (several tens of
+ * tasks), but don't want them to all run at once, you should only queue a
+ * limited number of them (around ten) at a time.
*
* Since: 2.36
*/
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index d362f9478..703a0b3a5 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -380,7 +380,7 @@ _g_test_watcher_remove_pid (GPid pid)
*
* An example of a test fixture for D-Bus services can be found
* here:
- * [gdbus-test-fixture.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-test-fixture.c)
+ * [gdbus-test-fixture.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-test-fixture.c)
*
* Note that these examples only deal with isolating the D-Bus aspect of your
* service. To successfully run isolated unit tests on your service you may need
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index b246e0c87..308a0a7ed 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -63,6 +63,12 @@ enum
PROP_ISSUER,
PROP_PKCS11_URI,
PROP_PRIVATE_KEY_PKCS11_URI,
+ PROP_NOT_VALID_BEFORE,
+ PROP_NOT_VALID_AFTER,
+ PROP_SUBJECT_NAME,
+ PROP_ISSUER_NAME,
+ PROP_DNS_NAMES,
+ PROP_IP_ADDRESSES,
};
static void
@@ -78,6 +84,8 @@ g_tls_certificate_get_property (GObject *object,
{
switch (prop_id)
{
+ case PROP_PRIVATE_KEY:
+ case PROP_PRIVATE_KEY_PEM:
case PROP_PKCS11_URI:
case PROP_PRIVATE_KEY_PKCS11_URI:
/* Subclasses must override this property but this allows older backends to not fatally error */
@@ -148,17 +156,25 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
- * GTlsCertificate:private-key:
+ * GTlsCertificate:private-key: (nullable)
*
* The DER (binary) encoded representation of the certificate's
- * private key, in either PKCS#1 format or unencrypted PKCS#8
- * format. This property (or the #GTlsCertificate:private-key-pem
- * property) can be set when constructing a key (eg, from a file),
- * but cannot be read.
+ * private key, in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017)
+ * or unencrypted [PKCS \#8 format.](https://datatracker.ietf.org/doc/html/rfc5208)
+ * PKCS \#8 format is supported since 2.32; earlier releases only
+ * support PKCS \#1. You can use the `openssl rsa` tool to convert
+ * PKCS \#8 keys to PKCS \#1.
*
- * PKCS#8 format is supported since 2.32; earlier releases only
- * support PKCS#1. You can use the `openssl rsa`
- * tool to convert PKCS#8 keys to PKCS#1.
+ * This property (or the #GTlsCertificate:private-key-pem property)
+ * can be set when constructing a key (for example, from a file).
+ * Since GLib 2.70, it is now also readable; however, be aware that if
+ * the private key is backed by a PKCS \#11 URI – for example, if it
+ * is stored on a smartcard – then this property will be %NULL. If so,
+ * the private key must be referenced via its PKCS \#11 URI,
+ * #GTlsCertificate:private-key-pkcs11-uri. You must check both
+ * properties to see if the certificate really has a private key.
+ * When this property is read, the output format will be unencrypted
+ * PKCS \#8.
*
* Since: 2.28
*/
@@ -167,22 +183,30 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
P_("Private key"),
P_("The DER representation of the certificate’s private key"),
G_TYPE_BYTE_ARRAY,
- G_PARAM_WRITABLE |
+ G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
- * GTlsCertificate:private-key-pem:
+ * GTlsCertificate:private-key-pem: (nullable)
*
* The PEM (ASCII) encoded representation of the certificate's
- * private key in either PKCS#1 format ("`BEGIN RSA PRIVATE
- * KEY`") or unencrypted PKCS#8 format ("`BEGIN
- * PRIVATE KEY`"). This property (or the
- * #GTlsCertificate:private-key property) can be set when
- * constructing a key (eg, from a file), but cannot be read.
+ * private key in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017)
+ * ("`BEGIN RSA PRIVATE KEY`") or unencrypted
+ * [PKCS \#8 format](https://datatracker.ietf.org/doc/html/rfc5208)
+ * ("`BEGIN PRIVATE KEY`"). PKCS \#8 format is supported since 2.32;
+ * earlier releases only support PKCS \#1. You can use the `openssl rsa`
+ * tool to convert PKCS \#8 keys to PKCS \#1.
*
- * PKCS#8 format is supported since 2.32; earlier releases only
- * support PKCS#1. You can use the `openssl rsa`
- * tool to convert PKCS#8 keys to PKCS#1.
+ * This property (or the #GTlsCertificate:private-key property)
+ * can be set when constructing a key (for example, from a file).
+ * Since GLib 2.70, it is now also readable; however, be aware that if
+ * the private key is backed by a PKCS \#11 URI - for example, if it
+ * is stored on a smartcard - then this property will be %NULL. If so,
+ * the private key must be referenced via its PKCS \#11 URI,
+ * #GTlsCertificate:private-key-pkcs11-uri. You must check both
+ * properties to see if the certificate really has a private key.
+ * When this property is read, the output format will be unencrypted
+ * PKCS \#8.
*
* Since: 2.28
*/
@@ -191,7 +215,7 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
P_("Private key (PEM)"),
P_("The PEM representation of the certificate’s private key"),
NULL,
- G_PARAM_WRITABLE |
+ G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
@@ -216,10 +240,10 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
/**
* GTlsCertificate:pkcs11-uri: (nullable)
*
- * A URI referencing the PKCS \#11 objects containing an X.509 certificate
- * and optionally a private key.
+ * A URI referencing the [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html)
+ * objects containing an X.509 certificate and optionally a private key.
*
- * If %NULL the certificate is either not backed by PKCS \#11 or the
+ * If %NULL, the certificate is either not backed by PKCS \#11 or the
* #GTlsBackend does not support PKCS \#11.
*
* Since: 2.68
@@ -236,7 +260,8 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
/**
* GTlsCertificate:private-key-pkcs11-uri: (nullable)
*
- * A URI referencing a PKCS \#11 object containing a private key.
+ * A URI referencing a [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html)
+ * object containing a private key.
*
* Since: 2.68
*/
@@ -248,6 +273,101 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsCertificate:not-valid-before: (nullable)
+ *
+ * The time at which this cert is considered to be valid,
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_NOT_VALID_BEFORE,
+ g_param_spec_boxed ("not-valid-before",
+ P_("Not Valid Before"),
+ P_("Cert should not be considered valid before this time."),
+ G_TYPE_DATE_TIME,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsCertificate:not-valid-after: (nullable)
+ *
+ * The time at which this cert is no longer valid,
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_NOT_VALID_AFTER,
+ g_param_spec_boxed ("not-valid-after",
+ P_("Not Valid after"),
+ P_("Cert should not be considered valid after this time."),
+ G_TYPE_DATE_TIME,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsCertificate:subject-name: (nullable)
+ *
+ * The subject from the cert,
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_SUBJECT_NAME,
+ g_param_spec_string ("subject-name",
+ P_("Subject Name"),
+ P_("The subject name from the certificate."),
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+ /**
+ * GTlsCertificate:issuer-name: (nullable)
+ *
+ * The issuer from the certificate,
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_ISSUER_NAME,
+ g_param_spec_string ("issuer-name",
+ P_("Issuer Name"),
+ P_("The issuer from the certificate."),
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsCertificate:dns-names: (nullable) (element-type GBytes) (transfer container)
+ *
+ * The DNS names from the certificate's Subject Alternative Names (SANs),
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_DNS_NAMES,
+ g_param_spec_boxed ("dns-names",
+ P_("DNS Names"),
+ P_("DNS Names listed on the cert."),
+ G_TYPE_PTR_ARRAY,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsCertificate:ip-addresses: (nullable) (element-type GInetAddress) (transfer container)
+ *
+ * The IP addresses from the certificate's Subject Alternative Names (SANs),
+ * %NULL if unavailable.
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_IP_ADDRESSES,
+ g_param_spec_boxed ("ip-addresses",
+ P_("IP Addresses"),
+ P_("IP Addresses listed on the cert."),
+ G_TYPE_PTR_ARRAY,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
}
static GTlsCertificate *
@@ -653,13 +773,14 @@ g_tls_certificate_new_from_files (const gchar *cert_file,
* @private_key_pkcs11_uri: (nullable): A PKCS \#11 URI
* @error: #GError for error reporting, or %NULL to ignore.
*
- * Creates a #GTlsCertificate from a PKCS \#11 URI.
+ * Creates a #GTlsCertificate from a
+ * [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) URI.
*
* An example @pkcs11_uri would be `pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01`
*
* Where the token’s layout is:
*
- * ```
+ * |[
* Object 0:
* URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=private%20key;type=private
* Type: Private key (RSA-2048)
@@ -669,7 +790,7 @@ g_tls_certificate_new_from_files (const gchar *cert_file,
* URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=Certificate%20for%20Authentication;type=cert
* Type: X.509 Certificate (RSA-2048)
* ID: 01
- * ```
+ * ]|
*
* In this case the certificate and private key would both be detected and used as expected.
* @pkcs_uri may also just reference an X.509 certificate object and then optionally
@@ -877,3 +998,138 @@ g_tls_certificate_is_same (GTlsCertificate *cert_one,
return equal;
}
+
+
+/**
+ * g_tls_certificate_get_not_valid_before:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the time at which the certificate became or will become valid.
+ *
+ * Returns: (nullable) (transfer full): The not-valid-before date, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GDateTime *
+g_tls_certificate_get_not_valid_before (GTlsCertificate *cert)
+{
+ GDateTime *not_valid_before = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "not-valid-before", &not_valid_before, NULL);
+
+ return g_steal_pointer (&not_valid_before);
+}
+
+/**
+ * g_tls_certificate_get_not_valid_after:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the time at which the certificate became or will become invalid.
+ *
+ * Returns: (nullable) (transfer full): The not-valid-after date, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GDateTime *
+g_tls_certificate_get_not_valid_after (GTlsCertificate *cert)
+{
+ GDateTime *not_valid_after = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "not-valid-after", &not_valid_after, NULL);
+
+ return g_steal_pointer (&not_valid_after);
+}
+
+/**
+ * g_tls_certificate_get_subject_name:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the subject name from the certificate.
+ *
+ * Returns: (nullable) (transfer full): The subject name, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+gchar *
+g_tls_certificate_get_subject_name (GTlsCertificate *cert)
+{
+ gchar *subject_name = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "subject-name", &subject_name, NULL);
+
+ return g_steal_pointer (&subject_name);
+}
+
+/**
+ * g_tls_certificate_get_issuer_name:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the issuer name from the certificate.
+ *
+ * Returns: (nullable) (transfer full): The issuer name, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+gchar *
+g_tls_certificate_get_issuer_name (GTlsCertificate *cert)
+{
+ gchar *issuer_name = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "issuer-name", &issuer_name, NULL);
+
+ return g_steal_pointer (&issuer_name);
+}
+
+/**
+ * g_tls_certificate_get_dns_names:
+ * @cert: a #GTlsCertificate
+ *
+ * Gets the value of #GTlsCertificate:dns-names.
+ *
+ * Returns: (nullable) (element-type GBytes) (transfer container): A #GPtrArray of
+ * #GBytes elements, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GPtrArray *
+g_tls_certificate_get_dns_names (GTlsCertificate *cert)
+{
+ GPtrArray *dns_names = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "dns-names", &dns_names, NULL);
+
+ return g_steal_pointer (&dns_names);
+}
+
+/**
+ * g_tls_certificate_get_ip_addresses:
+ * @cert: a #GTlsCertificate
+ *
+ * Gets the value of #GTlsCertificate:ip-addresses.
+ *
+ * Returns: (nullable) (element-type GInetAddress) (transfer container): A #GPtrArray
+ * of #GInetAddress elements, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GPtrArray *
+g_tls_certificate_get_ip_addresses (GTlsCertificate *cert)
+{
+ GPtrArray *ip_addresses = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+ g_object_get (G_OBJECT (cert), "ip-addresses", &ip_addresses, NULL);
+
+ return g_steal_pointer (&ip_addresses);
+}
diff --git a/gio/gtlscertificate.h b/gio/gtlscertificate.h
index ead4f015e..3b92b97fc 100644
--- a/gio/gtlscertificate.h
+++ b/gio/gtlscertificate.h
@@ -92,6 +92,24 @@ GLIB_AVAILABLE_IN_2_34
gboolean g_tls_certificate_is_same (GTlsCertificate *cert_one,
GTlsCertificate *cert_two);
+GLIB_AVAILABLE_IN_2_70
+GDateTime *g_tls_certificate_get_not_valid_before (GTlsCertificate *cert);
+
+GLIB_AVAILABLE_IN_2_70
+GDateTime *g_tls_certificate_get_not_valid_after (GTlsCertificate *cert);
+
+GLIB_AVAILABLE_IN_2_70
+gchar *g_tls_certificate_get_subject_name (GTlsCertificate *cert);
+
+GLIB_AVAILABLE_IN_2_70
+gchar *g_tls_certificate_get_issuer_name (GTlsCertificate *cert);
+
+GLIB_AVAILABLE_IN_2_70
+GPtrArray *g_tls_certificate_get_dns_names (GTlsCertificate *cert);
+
+GLIB_AVAILABLE_IN_2_70
+GPtrArray *g_tls_certificate_get_ip_addresses (GTlsCertificate *cert);
+
G_END_DECLS
#endif /* __G_TLS_CERTIFICATE_H__ */
diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c
index 5654ca9ee..0239489b7 100644
--- a/gio/gtlsconnection.c
+++ b/gio/gtlsconnection.c
@@ -55,12 +55,7 @@
* Since: 2.28
*/
-struct _GTlsConnectionPrivate
-{
- gchar *negotiated_protocol;
-};
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
+G_DEFINE_ABSTRACT_TYPE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
static void g_tls_connection_get_property (GObject *object,
guint prop_id,
@@ -70,7 +65,6 @@ static void g_tls_connection_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
-static void g_tls_connection_finalize (GObject *object);
enum {
ACCEPT_CERTIFICATE,
@@ -93,6 +87,8 @@ enum {
PROP_PEER_CERTIFICATE_ERRORS,
PROP_ADVERTISED_PROTOCOLS,
PROP_NEGOTIATED_PROTOCOL,
+ PROP_PROTOCOL_VERSION,
+ PROP_CIPHERSUITE_NAME,
};
static void
@@ -102,7 +98,6 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
gobject_class->get_property = g_tls_connection_get_property;
gobject_class->set_property = g_tls_connection_set_property;
- gobject_class->finalize = g_tls_connection_finalize;
/**
* GTlsConnection:base-io-stream:
@@ -296,6 +291,37 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
G_PARAM_STATIC_STRINGS));
/**
+ * GTlsConnection:protocol-version:
+ *
+ * The TLS protocol version in use. See g_tls_connection_get_protocol_version().
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_PROTOCOL_VERSION,
+ g_param_spec_enum ("protocol-version",
+ P_("Protocol Version"),
+ P_("TLS protocol version negotiated for this connection"),
+ G_TYPE_TLS_PROTOCOL_VERSION,
+ G_TLS_PROTOCOL_VERSION_UNKNOWN,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GTlsConnection:ciphersuite-name: (nullable)
+ *
+ * The name of the TLS ciphersuite in use. See g_tls_connection_get_ciphersuite_name().
+ *
+ * Since: 2.70
+ */
+ g_object_class_install_property (gobject_class, PROP_CIPHERSUITE_NAME,
+ g_param_spec_string ("ciphersuite-name",
+ P_("Ciphersuite Name"),
+ P_("Name of ciphersuite negotiated for this connection"),
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* GTlsConnection::accept-certificate:
* @conn: a #GTlsConnection
* @peer_cert: the peer's #GTlsCertificate
@@ -380,17 +406,6 @@ g_tls_connection_set_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
-static void
-g_tls_connection_finalize (GObject *object)
-{
- GTlsConnection *conn = G_TLS_CONNECTION(object);
- GTlsConnectionPrivate *priv = g_tls_connection_get_instance_private (conn);
-
- g_clear_pointer (&priv->negotiated_protocol, g_free);
-
- G_OBJECT_CLASS (g_tls_connection_parent_class)->finalize (object);
-}
-
/**
* g_tls_connection_set_use_system_certdb:
* @conn: a #GTlsConnection
@@ -838,31 +853,15 @@ g_tls_connection_set_advertised_protocols (GTlsConnection *conn,
const gchar *
g_tls_connection_get_negotiated_protocol (GTlsConnection *conn)
{
- GTlsConnectionPrivate *priv;
- gchar *protocol;
+ GTlsConnectionClass *class;
g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
- g_object_get (G_OBJECT (conn),
- "negotiated-protocol", &protocol,
- NULL);
-
- /*
- * Cache the property internally so we can return a `const` pointer
- * to the caller.
- */
- priv = g_tls_connection_get_instance_private (conn);
- if (g_strcmp0 (priv->negotiated_protocol, protocol) != 0)
- {
- g_free (priv->negotiated_protocol);
- priv->negotiated_protocol = protocol;
- }
- else
- {
- g_free (protocol);
- }
+ class = G_TLS_CONNECTION_GET_CLASS (conn);
+ if (class->get_negotiated_protocol == NULL)
+ return NULL;
- return priv->negotiated_protocol;
+ return class->get_negotiated_protocol (conn);
}
/**
@@ -1029,6 +1028,69 @@ g_tls_connection_handshake_finish (GTlsConnection *conn,
}
/**
+ * g_tls_connection_get_protocol_version:
+ * @conn: a #GTlsConnection
+ *
+ * Returns the current TLS protocol version, which may be
+ * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or
+ * has been closed, or if the TLS backend has implemented a protocol version
+ * that is not a recognized #GTlsProtocolVersion.
+ *
+ * Returns: The current TLS protocol version
+ *
+ * Since: 2.70
+ */
+GTlsProtocolVersion
+g_tls_connection_get_protocol_version (GTlsConnection *conn)
+{
+ GTlsProtocolVersion protocol_version;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN);
+
+ g_object_get (G_OBJECT (conn),
+ "protocol-version", &protocol_version,
+ NULL);
+
+ /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */
+ enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION);
+ enum_value = g_enum_get_value (enum_class, protocol_version);
+ return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN;
+}
+
+/**
+ * g_tls_connection_get_ciphersuite_name:
+ * @conn: a #GTlsConnection
+ *
+ * Returns the name of the current TLS ciphersuite, or %NULL if the
+ * connection has not handshaked or has been closed. Beware that the TLS
+ * backend may use any of multiple different naming conventions, because
+ * OpenSSL and GnuTLS have their own ciphersuite naming conventions that
+ * are different from each other and different from the standard, IANA-
+ * registered ciphersuite names. The ciphersuite name is intended to be
+ * displayed to the user for informative purposes only, and parsing it
+ * is not recommended.
+ *
+ * Returns: (nullable): The name of the current TLS ciphersuite, or %NULL
+ *
+ * Since: 2.70
+ */
+gchar *
+g_tls_connection_get_ciphersuite_name (GTlsConnection *conn)
+{
+ gchar *ciphersuite_name;
+
+ g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
+
+ g_object_get (G_OBJECT (conn),
+ "ciphersuite-name", &ciphersuite_name,
+ NULL);
+
+ return g_steal_pointer (&ciphersuite_name);
+}
+
+/**
* g_tls_error_quark:
*
* Gets the TLS error quark.
diff --git a/gio/gtlsconnection.h b/gio/gtlsconnection.h
index 037222733..526eb60b5 100644
--- a/gio/gtlsconnection.h
+++ b/gio/gtlsconnection.h
@@ -43,6 +43,20 @@ struct _GTlsConnection {
GTlsConnectionPrivate *priv;
};
+/**
+ * GTlsConnectionClass:
+ * @parent_class: The parent class.
+ * @accept_certificate: Check whether to accept a certificate.
+ * @handshake: Perform a handshake operation.
+ * @handshake_async: Start an asynchronous handshake operation.
+ * @handshake_finish: Finish an asynchronous handshake operation.
+ * @get_binding_data: Retrieve TLS channel binding data (Since: 2.66)
+ * @get_negotiated_protocol: Get ALPN-negotiated protocol (Since: 2.70)
+ *
+ * The class structure for the #GTlsConnection type.
+ *
+ * Since: 2.28
+ */
struct _GTlsConnectionClass
{
GIOStreamClass parent_class;
@@ -73,9 +87,11 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GError **error);
G_GNUC_END_IGNORE_DEPRECATIONS
+ const gchar *(*get_negotiated_protocol) (GTlsConnection *conn);
+
/*< private >*/
/* Padding for future expansion */
- gpointer padding[7];
+ gpointer padding[6];
};
GLIB_AVAILABLE_IN_ALL
@@ -155,6 +171,12 @@ gboolean g_tls_connection_handshake_finish (GTlsConnecti
GAsyncResult *result,
GError **error);
+GLIB_AVAILABLE_IN_2_70
+GTlsProtocolVersion g_tls_connection_get_protocol_version (GTlsConnection *conn);
+
+GLIB_AVAILABLE_IN_2_70
+gchar * g_tls_connection_get_ciphersuite_name (GTlsConnection *conn);
+
/**
* G_TLS_ERROR:
*
diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
index 948e812df..f705bcb3f 100644
--- a/gio/gtlspassword.c
+++ b/gio/gtlspassword.c
@@ -241,9 +241,9 @@ g_tls_password_new (GTlsPasswordFlags flags,
}
/**
- * g_tls_password_get_value:
+ * g_tls_password_get_value: (virtual get_value)
* @password: a #GTlsPassword object
- * @length: (nullable): location to place the length of the password.
+ * @length: (optional): location to place the length of the password.
*
* Get the password value. If @length is not %NULL then it will be
* filled in with the length of the password value. (Note that the
@@ -251,7 +251,7 @@ g_tls_password_new (GTlsPasswordFlags flags,
* for @length in contexts where you know the password will have a
* certain fixed length.)
*
- * Returns: The password value (owned by the password object).
+ * Returns: (array length=length): The password value (owned by the password object).
*
* Since: 2.30
*/
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 32b936259..46a41fc41 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1593,7 +1593,9 @@ g_unix_mounts_get (guint64 *time_read)
* If more mounts have the same mount path, the last matching mount
* is returned.
*
- * Returns: (transfer full): a #GUnixMountEntry.
+ * This will return %NULL if there is no mount point at @mount_path.
+ *
+ * Returns: (transfer full) (nullable): a #GUnixMountEntry.
**/
GUnixMountEntry *
g_unix_mount_at (const char *mount_path,
@@ -1636,7 +1638,10 @@ g_unix_mount_at (const char *mount_path,
* If more mounts have the same mount path, the last matching mount
* is returned.
*
- * Returns: (transfer full): a #GUnixMountEntry.
+ * This will return %NULL if looking up the mount entry fails, if
+ * @file_path doesn’t exist or there is an I/O error.
+ *
+ * Returns: (transfer full) (nullable): a #GUnixMountEntry.
*
* Since: 2.52
**/
diff --git a/gio/gunixsocketaddress.c b/gio/gunixsocketaddress.c
index 0ab1a62e9..69204e9b9 100644
--- a/gio/gunixsocketaddress.c
+++ b/gio/gunixsocketaddress.c
@@ -214,7 +214,8 @@ g_unix_socket_address_to_native (GSocketAddress *address,
gssize socklen;
socklen = g_unix_socket_address_get_native_size (address);
- if (destlen < socklen)
+ g_assert (socklen >= 0);
+ if (destlen < (gsize) socklen)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
_("Not enough space for socket address"));
diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c
index 3468dfee0..5403225e2 100644
--- a/gio/gwin32appinfo.c
+++ b/gio/gwin32appinfo.c
@@ -1629,7 +1629,6 @@ process_uwp_verbs (GList *verbs,
continue;
}
- acid = NULL;
got_value = g_win32_registry_key_get_value_w (key,
g_win32_registry_get_os_dirs_w (),
TRUE,
@@ -3635,7 +3634,6 @@ grab_registry_string (GWin32RegistryKey *handler_appkey,
if (*destination != NULL)
return;
- value = NULL;
if (g_win32_registry_key_get_value_w (handler_appkey,
NULL,
TRUE,
@@ -3830,9 +3828,6 @@ update_registry_data (void)
return;
}
-static void
-watch_keys (void);
-
/* This function is called when any of our registry watchers detect
* changes in the registry.
*/
@@ -3840,7 +3835,6 @@ static void
keys_updated (GWin32RegistryKey *key,
gpointer user_data)
{
- watch_keys ();
/* Indicate the tree as not up-to-date, push a new job for the AppInfo thread */
g_atomic_int_inc (&gio_win32_appinfo_update_counter);
/* We don't use the data pointer, but it must be non-NULL */
@@ -4035,6 +4029,7 @@ gio_win32_appinfo_init (gboolean do_wait)
g_mutex_lock (&gio_win32_appinfo_mutex);
while (g_atomic_int_get (&gio_win32_appinfo_update_counter) > 0)
g_cond_wait (&gio_win32_appinfo_cond, &gio_win32_appinfo_mutex);
+ watch_keys ();
g_mutex_unlock (&gio_win32_appinfo_mutex);
}
}
diff --git a/gio/gwin32mount.c b/gio/gwin32mount.c
index 83d8695a1..f5be8adfa 100644
--- a/gio/gwin32mount.c
+++ b/gio/gwin32mount.c
@@ -25,7 +25,47 @@
#include <string.h>
#define WIN32_MEAN_AND_LEAN
+#define COBJMACROS
#include <windows.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+
+/* At the moment of writing IExtractIconW interface in Mingw-w64
+ * is missing IUnknown members in its vtable. Use our own
+ * fixed declaration for now.
+ */
+#undef INTERFACE
+#define INTERFACE IMyExtractIconW
+DECLARE_INTERFACE_(IMyExtractIconW,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IMyExtractIconW methods ***/
+ STDMETHOD(GetIconLocation)(THIS_ UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, PUINT pwFlags) PURE;
+ STDMETHOD(Extract)(THIS_ LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IMyExtractIconW_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IMyExtractIconW_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IMyExtractIconW_Release(p) (p)->lpVtbl->Release(p)
+/*** IMyExtractIconW methods ***/
+#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->lpVtbl->GetIconLocation(p,a,b,c,d,e)
+#define IMyExtractIconW_Extract(p,a,b,c,d,e) (p)->lpVtbl->Extract(p,a,b,c,d,e)
+#else
+/*** IUnknown methods ***/
+#define IMyExtractIconW_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IMyExtractIconW_AddRef(p) (p)->AddRef()
+#define IMyExtractIconW_Release(p) (p)->Release()
+/*** IMyExtractIconW methods ***/
+#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->GetIconLocation(p,a,b,c,d,e)
+#define IMyExtractIconW_Extract(p,a,b,c,d,e) (p)->Extract(p,a,b,c,d,e)
+#endif
+
#include <glib.h>
#include "gwin32volumemonitor.h"
@@ -103,14 +143,52 @@ g_win32_mount_init (GWin32Mount *win32_mount)
{
}
+/* wdrive doesn't need to end with a path separator.
+ wdrive must use backslashes as path separators, not slashes.
+ IShellFolder::ParseDisplayName() takes non-const string as input,
+ so wdrive can't be a const string.
+ Returns the name on success (free with g_free),
+ NULL otherwise.
+ */
+static gchar *
+get_mount_display_name (gunichar2 *wdrive)
+{
+ IShellFolder *desktop;
+ PIDLIST_RELATIVE volume;
+ STRRET volume_name;
+ gchar *result = NULL;
+
+ /* Get the desktop folder object reference */
+ if (!SUCCEEDED (SHGetDesktopFolder (&desktop)))
+ return result;
+
+ if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, wdrive, NULL, &volume, NULL)))
+ {
+ volume_name.uType = STRRET_WSTR;
+
+ if (SUCCEEDED (IShellFolder_GetDisplayNameOf (desktop, volume, SHGDN_FORADDRESSBAR, &volume_name)))
+ {
+ wchar_t *volume_name_wchar;
+
+ if (SUCCEEDED (StrRetToStrW (&volume_name, volume, &volume_name_wchar)))
+ {
+ result = g_utf16_to_utf8 (volume_name_wchar, -1, NULL, NULL, NULL);
+ CoTaskMemFree (volume_name_wchar);
+ }
+ }
+ CoTaskMemFree (volume);
+ }
+
+ IShellFolder_Release (desktop);
+
+ return result;
+}
+
static gchar *
_win32_get_displayname (const char *drive)
{
gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);
- gchar *name = NULL;
- SHFILEINFOW sfi;
- if (SHGetFileInfoW(wdrive, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME))
- name = g_utf16_to_utf8 (sfi.szDisplayName, -1, NULL, NULL, NULL);
+ gchar *name = get_mount_display_name (wdrive);
g_free (wdrive);
return name ? name : g_strdup (drive);
@@ -210,6 +288,92 @@ _win32_drive_type_to_icon (int type, gboolean use_symbolic)
}
}
+/* mount_path doesn't need to end with a path separator.
+ mount_path must use backslashes as path separators, not slashes.
+ IShellFolder::ParseDisplayName() takes non-const string as input,
+ so mount_path can't be a const string.
+ result_name and result_index must not be NULL.
+ Returns TRUE when result_name is set (free with g_free),
+ FALSE otherwise.
+ */
+static gboolean
+get_icon_name_index (wchar_t *mount_path,
+ wchar_t **result_name,
+ int *result_index)
+{
+ IShellFolder *desktop;
+ PIDLIST_RELATIVE volume;
+ IShellFolder *volume_parent;
+ PCUITEMID_CHILD volume_relative;
+ IMyExtractIconW *eicon;
+ int icon_index;
+ UINT icon_flags;
+ wchar_t *name_buffer;
+ gsize name_buffer_size;
+ gsize arbitrary_reasonable_limit = 5000;
+ gboolean result = FALSE;
+
+ *result_name = NULL;
+
+ /* Get the desktop folder object reference */
+ if (!SUCCEEDED (SHGetDesktopFolder (&desktop)))
+ return FALSE;
+
+ /* Construct the volume IDList relative to desktop */
+ if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, mount_path, NULL, &volume, NULL)))
+ {
+ /* Get the parent of the volume (transfer-full) and the IDList relative to parent (transfer-none) */
+ if (SUCCEEDED (SHBindToParent (volume, &IID_IShellFolder, (void **) &volume_parent, &volume_relative)))
+ {
+ /* Get a reference to IExtractIcon object for the volume */
+ if (SUCCEEDED (IShellFolder_GetUIObjectOf (volume_parent, NULL, 1, (LPCITEMIDLIST *) &volume_relative, &IID_IExtractIconW, NULL, (void **) &eicon)))
+ {
+ gboolean keep_going = TRUE;
+ name_buffer = NULL;
+ name_buffer_size = MAX_PATH / 2;
+ while (keep_going)
+ {
+ name_buffer_size *= 2;
+ name_buffer = g_renew (wchar_t, name_buffer, name_buffer_size);
+ name_buffer[name_buffer_size - 1] = 0x1; /* sentinel */
+ keep_going = FALSE;
+
+ /* Try to get the icon location */
+ if (SUCCEEDED (IMyExtractIconW_GetIconLocation (eicon, GIL_FORSHELL, name_buffer, name_buffer_size, &icon_index, &icon_flags)))
+ {
+ if (name_buffer[name_buffer_size - 1] != 0x1)
+ {
+ if (name_buffer_size < arbitrary_reasonable_limit)
+ {
+ /* Buffer was too small, keep going */
+ keep_going = TRUE;
+ continue;
+ }
+ /* Else stop trying */
+ }
+ /* name_buffer might not contain a name */
+ else if ((icon_flags & GIL_NOTFILENAME) != GIL_NOTFILENAME)
+ {
+ *result_name = g_steal_pointer (&name_buffer);
+ *result_index = icon_index;
+ result = TRUE;
+ }
+ }
+ }
+
+ g_free (name_buffer);
+ IMyExtractIconW_Release (eicon);
+ }
+ IShellFolder_Release (volume_parent);
+ }
+ CoTaskMemFree (volume);
+ }
+
+ IShellFolder_Release (desktop);
+
+ return result;
+}
+
static GIcon *
g_win32_mount_get_icon (GMount *mount)
{
@@ -220,15 +384,20 @@ g_win32_mount_get_icon (GMount *mount)
/* lazy creation */
if (!win32_mount->icon)
{
- SHFILEINFOW shfi;
+ wchar_t *icon_path;
+ int icon_index;
+ wchar_t *p;
wchar_t *wfn = g_utf8_to_utf16 (win32_mount->mount_path, -1, NULL, NULL, NULL);
- if (SHGetFileInfoW (wfn, 0, &shfi, sizeof (shfi), SHGFI_ICONLOCATION))
+ for (p = wfn; p != NULL && *p != 0; p++)
+ if (*p == L'/')
+ *p = L'\\';
+
+ if (get_icon_name_index (wfn, &icon_path, &icon_index))
{
- gchar *name = g_utf16_to_utf8 (shfi.szDisplayName, -1, NULL, NULL, NULL);
- gchar *id = g_strdup_printf ("%s,%i", name, shfi.iIcon);
+ gchar *id = g_strdup_printf ("%S,%i", icon_path, icon_index);
+ g_free (icon_path);
win32_mount->icon = g_themed_icon_new (id);
- g_free (name);
g_free (id);
}
else
diff --git a/gio/gwin32packageparser.c b/gio/gwin32packageparser.c
index ee05bb1dd..ad5302270 100755
--- a/gio/gwin32packageparser.c
+++ b/gio/gwin32packageparser.c
@@ -390,7 +390,7 @@ g_win32_package_parser_enum_packages (GWin32PackageParserCallback callback,
wcs_path = LoadedWindowsGetStringRawBuffer (path, NULL);
manifest_filename_size = wcslen (wcs_path) + wcslen (bslash_appmanifest);
manifest_filename = g_new (wchar_t, manifest_filename_size + 1);
- memcpy (manifest_filename, wcs_path, wcslen (wcs_path) * sizeof (wchar_t));
+ memcpy (manifest_filename, wcs_path, manifest_filename_size * sizeof (wchar_t));
memcpy (&manifest_filename[wcslen (wcs_path)], bslash_appmanifest, (wcslen (bslash_appmanifest) + 1) * sizeof (wchar_t));
memset (sax, 0, sizeof (*sax));
diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
index 5e2b006dd..398d8f45b 100644
--- a/gio/gwin32registrykey.c
+++ b/gio/gwin32registrykey.c
@@ -2425,20 +2425,17 @@ key_changed (PVOID closure,
ULONG reserved)
{
GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (closure);
- gpointer user_data;
- GWin32RegistryKeyWatchCallbackFunc callback;
-
- callback = g_steal_pointer (&key->priv->callback);
- user_data = g_steal_pointer (&key->priv->user_data);
g_free (status_block);
g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_CHANGED);
g_atomic_int_set (&key->priv->watch_indicator, G_WIN32_KEY_UNWATCHED);
key->priv->update_flags = G_WIN32_REGISTRY_UPDATED_NOTHING;
- if (callback)
- callback (key, user_data);
+ if (key->priv->callback)
+ key->priv->callback (key, key->priv->user_data);
+ key->priv->callback = NULL;
+ key->priv->user_data = NULL;
g_object_unref (key);
}
@@ -2553,7 +2550,9 @@ g_win32_registry_key_watch (GWin32RegistryKey *key,
0,
TRUE);
- if (status == STATUS_PENDING || status == STATUS_SUCCESS)
+ g_assert (status != STATUS_SUCCESS);
+
+ if (status == STATUS_PENDING)
return TRUE;
g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNKNOWN);
diff --git a/gio/tests/actions.c b/gio/tests/actions.c
index c183c7aa1..91fc08074 100644
--- a/gio/tests/actions.c
+++ b/gio/tests/actions.c
@@ -151,7 +151,7 @@ strv_strv_cmp (gchar **a, gchar **b)
static gboolean
strv_set_equal (gchar **strv, ...)
{
- gint count;
+ guint count;
va_list list;
const gchar *str;
gboolean res;
@@ -372,10 +372,10 @@ static void
test_entries (void)
{
const GActionEntry entries[] = {
- { "foo", activate_foo },
- { "bar", activate_bar, "s" },
- { "toggle", NULL, NULL, "false" },
- { "volume", NULL, NULL, "0", change_volume_state }
+ { "foo", activate_foo, NULL, NULL, NULL, { 0 } },
+ { "bar", activate_bar, "s", NULL, NULL, { 0 } },
+ { "toggle", NULL, NULL, "false", NULL, { 0 } },
+ { "volume", NULL, NULL, "0", change_volume_state, { 0 } },
};
GSimpleActionGroup *actions;
GVariant *state;
@@ -399,10 +399,10 @@ test_entries (void)
if (g_test_undefined ())
{
const GActionEntry bad_type = {
- "bad-type", NULL, "ss"
+ "bad-type", NULL, "ss", NULL, NULL, { 0 }
};
const GActionEntry bad_state = {
- "bad-state", NULL, NULL, "flse"
+ "bad-state", NULL, NULL, "flse", NULL, { 0 }
};
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
@@ -468,7 +468,7 @@ test_parse_detailed (void)
{ "abc(42, 4)", "abc", "(42, 4)", "expected end of input", NULL },
{ "abc(42,)", "abc", "(42,)", "expected end of input", NULL }
};
- gint i;
+ gsize i;
for (i = 0; i < G_N_ELEMENTS (testcases); i++)
{
@@ -638,13 +638,13 @@ stop_loop (gpointer data)
}
static GActionEntry exported_entries[] = {
- { "undo", activate_action, NULL, NULL, NULL },
- { "redo", activate_action, NULL, NULL, NULL },
- { "cut", activate_action, NULL, NULL, NULL },
- { "copy", activate_action, NULL, NULL, NULL },
- { "paste", activate_action, NULL, NULL, NULL },
- { "bold", activate_toggle, NULL, "true", NULL },
- { "lang", activate_radio, "s", "'latin'", NULL },
+ { "undo", activate_action, NULL, NULL, NULL, { 0 } },
+ { "redo", activate_action, NULL, NULL, NULL, { 0 } },
+ { "cut", activate_action, NULL, NULL, NULL, { 0 } },
+ { "copy", activate_action, NULL, NULL, NULL, { 0 } },
+ { "paste", activate_action, NULL, NULL, NULL, { 0 } },
+ { "bold", activate_toggle, NULL, "true", NULL, { 0 } },
+ { "lang", activate_radio, "s", "'latin'", NULL, { 0 } },
};
static void
@@ -920,8 +920,8 @@ test_dbus_threaded (void)
GSimpleActionGroup *group[10];
GThread *export[10];
static GActionEntry entries[] = {
- { "a", activate_action, NULL, NULL, NULL },
- { "b", activate_action, NULL, NULL, NULL },
+ { "a", activate_action, NULL, NULL, NULL, { 0 } },
+ { "b", activate_action, NULL, NULL, NULL, { 0 } },
};
gint i;
diff --git a/gio/tests/appinfo.c b/gio/tests/appinfo.c
index 2f0f43074..bd76729c4 100644
--- a/gio/tests/appinfo.c
+++ b/gio/tests/appinfo.c
@@ -104,7 +104,7 @@ test_launch_no_app_id (void)
"Exec=%s/appinfo-test --option %%u %%i --name %%c --filename %%k %%m %%%%",
g_test_get_dir (G_TEST_BUILT));
- g_test_bug ("791337");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=791337");
for (i = 0; i < G_N_ELEMENTS (exec_line_variants); i++)
{
@@ -581,7 +581,6 @@ main (int argc, char *argv[])
g_setenv ("XDG_CURRENT_DESKTOP", "GNOME", TRUE);
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
g_test_add_func ("/appinfo/basic", test_basic);
g_test_add_func ("/appinfo/text", test_text);
diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c
index 00e068766..a14c413c2 100644
--- a/gio/tests/async-close-output-stream.c
+++ b/gio/tests/async-close-output-stream.c
@@ -164,7 +164,7 @@ test_without_flush (SetupData *data,
{
prepare_data (data, FALSE);
- g_test_bug ("617937");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
/* just close asynchronously */
g_output_stream_close_async (data->conv_stream,
@@ -181,7 +181,7 @@ test_with_flush (SetupData *data, gconstpointer user_data)
{
GError *error = NULL;
- g_test_bug ("617937");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
prepare_data (data, TRUE);
@@ -222,7 +222,7 @@ static void
test_with_async_flush (SetupData *data,
gconstpointer user_data)
{
- g_test_bug ("617937");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
prepare_data (data, TRUE);
@@ -244,8 +244,6 @@ main (int argc,
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
data = g_slice_new (SetupData);
/* test closing asynchronously without flushing manually */
diff --git a/gio/tests/basic-application.c b/gio/tests/basic-application.c
index 94100eb5f..362b2fd51 100644
--- a/gio/tests/basic-application.c
+++ b/gio/tests/basic-application.c
@@ -54,10 +54,10 @@ static void
startup (GApplication *app)
{
static GActionEntry actions[] = {
- { "new", new_activated, NULL, NULL, NULL },
- { "quit", quit_activated, NULL, NULL, NULL },
- { "action1", action1_activated, NULL, NULL, NULL },
- { "action2", action2_activated, "b", "false", change_action2 }
+ { "new", new_activated, NULL, NULL, NULL, { 0 } },
+ { "quit", quit_activated, NULL, NULL, NULL, { 0 } },
+ { "action1", action1_activated, NULL, NULL, NULL, { 0 } },
+ { "action2", action2_activated, "b", "false", change_action2, { 0 } }
};
g_action_map_add_action_entries (G_ACTION_MAP (app),
diff --git a/gio/tests/buffered-input-stream.c b/gio/tests/buffered-input-stream.c
index ef865fc45..ee084b3b7 100644
--- a/gio/tests/buffered-input-stream.c
+++ b/gio/tests/buffered-input-stream.c
@@ -126,7 +126,7 @@ test_read_byte (void)
GInputStream *in;
GError *error;
- g_test_bug ("562393");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=562393");
base = g_memory_input_stream_new_from_data ("abcdefgh", -1, NULL);
in = g_buffered_input_stream_new (base);
@@ -536,7 +536,6 @@ main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/buffered-input-stream/peek", test_peek);
g_test_add_func ("/buffered-input-stream/peek-buffer", test_peek_buffer);
diff --git a/gio/tests/contenttype.c b/gio/tests/contenttype.c
index 71e8b0df6..db34f1da8 100644
--- a/gio/tests/contenttype.c
+++ b/gio/tests/contenttype.c
@@ -363,7 +363,7 @@ test_tree (void)
const gchar *path;
GFile *file;
gchar **types;
- gint i;
+ gsize i;
#ifdef __APPLE__
g_test_skip ("The OSX backend does not implement g_content_type_guess_for_tree()");
@@ -390,7 +390,7 @@ test_type_is_a_special_case (void)
#else
gboolean res;
- g_test_bug ("782311");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=782311");
/* Everything but the inode type is application/octet-stream */
res = g_content_type_is_a ("inode/directory", "application/octet-stream");
@@ -463,8 +463,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/contenttype/guess", test_guess);
g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data);
g_test_add_func ("/contenttype/mime_from_content", test_mime_from_content);
diff --git a/gio/tests/contexts.c b/gio/tests/contexts.c
index c6dc26111..3b64c7622 100644
--- a/gio/tests/contexts.c
+++ b/gio/tests/contexts.c
@@ -360,7 +360,8 @@ test_context_specific_emit (void)
{
GThread *threads[N_THREADS];
gboolean exited = FALSE;
- guint i, n;
+ gsize i;
+ gint k, n;
for (i = 0; i < N_THREADS; i++)
threads[i] = g_thread_new ("test", test_emit_thread, &observed_values[i]);
@@ -368,7 +369,7 @@ test_context_specific_emit (void)
/* make changes and ensure that they are observed */
for (n = 0; n < 1000; n++)
{
- guint64 expiry;
+ gint64 expiry;
/* don't burn CPU forever */
expiry = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
@@ -376,7 +377,7 @@ test_context_specific_emit (void)
g_atomic_int_set (&current_value, n);
/* wake them to notice */
- for (i = 0; i < g_test_rand_int_range (1, 5); i++)
+ for (k = 0; k < g_test_rand_int_range (1, 5); k++)
g_context_specific_group_emit (&group, g_signal_lookup ("changed", per_thread_thing_get_type ()));
for (i = 0; i < N_THREADS; i++)
diff --git a/gio/tests/converter-stream.c b/gio/tests/converter-stream.c
index 8bec95c76..cf1853ba0 100644
--- a/gio/tests/converter-stream.c
+++ b/gio/tests/converter-stream.c
@@ -94,7 +94,7 @@ g_expander_converter_convert (GConverter *converter,
{
const guint8 *in, *in_end;
guint8 v, *out;
- int i;
+ gsize i;
gsize block_size;
in = inbuf;
@@ -210,7 +210,7 @@ g_compressor_converter_convert (GConverter *converter,
{
const guint8 *in, *in_end;
guint8 v, *out;
- int i;
+ gsize i;
gsize block_size;
in = inbuf;
@@ -231,7 +231,7 @@ g_compressor_converter_convert (GConverter *converter,
block_size = v * 1000;
/* Not enough data */
- if (in_end - in < block_size)
+ if ((gsize) (in_end - in) < block_size)
{
if (*bytes_read > 0)
break;
@@ -254,7 +254,7 @@ g_compressor_converter_convert (GConverter *converter,
}
}
- if (v == 0 && in_end - in == block_size && (flags & G_CONVERTER_INPUT_AT_END) == 0)
+ if (v == 0 && (gsize) (in_end - in) == block_size && (flags & G_CONVERTER_INPUT_AT_END) == 0)
{
if (*bytes_read > 0)
break;
@@ -297,7 +297,7 @@ test_expander (void)
GConverter *expander;
GConverter *converter;
GError *error;
- int i;
+ gsize i;
expander = g_expander_converter_new ();
@@ -393,7 +393,7 @@ test_compressor (void)
GOutputStream *mem_out, *cstream_out;
GConverter *expander, *compressor;
GError *error;
- int i;
+ gsize i;
expander = g_expander_converter_new ();
expanded = g_malloc (100*1000); /* Large enough */
@@ -748,7 +748,7 @@ test_roundtrip (gconstpointer data)
GFileInfo *info;
GFileInfo *info2;
- g_test_bug ("619945");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=619945");
data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
for (i = 0; i < DATA_LENGTH; i++)
@@ -972,7 +972,7 @@ test_converter_pollable (void)
GPollableOutputStream *pollable_out;
GConverter *expander, *compressor;
GError *error;
- int i;
+ gsize i;
expander = g_expander_converter_new ();
expanded = g_malloc (100*1000); /* Large enough */
@@ -1207,12 +1207,10 @@ main (int argc,
{ "/converter-input-stream/charset/fallbacks", "UTF-8", "Some characters just don't fit into latin1: πא", "ISO-8859-1", "Some characters just don't fit into latin1: \\CF\\80\\D7\\90", 4 },
};
- gint i;
+ gsize i;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/converter/basics", test_converter_basics);
g_test_add_func ("/converter-input-stream/expander", test_expander);
g_test_add_func ("/converter-input-stream/compressor", test_compressor);
diff --git a/gio/tests/dbus-appinfo.c b/gio/tests/dbus-appinfo.c
index 7e2fc4d79..86bdfebee 100644
--- a/gio/tests/dbus-appinfo.c
+++ b/gio/tests/dbus-appinfo.c
@@ -174,10 +174,10 @@ test_application_quit (GSimpleAction *action,
}
static const GActionEntry app_actions[] = {
- { "frob", test_application_frob },
- { "tweak", test_application_tweak },
- { "twiddle", test_application_twiddle },
- { "quit", test_application_quit }
+ { "frob", test_application_frob, NULL, NULL, NULL, { 0 } },
+ { "tweak", test_application_tweak, NULL, NULL, NULL, { 0 } },
+ { "twiddle", test_application_twiddle, NULL, NULL, NULL, { 0 } },
+ { "quit", test_application_quit, NULL, NULL, NULL, { 0 } }
};
static void
diff --git a/gio/tests/echo-server.c b/gio/tests/echo-server.c
index 7634b5bb0..83d1d32db 100644
--- a/gio/tests/echo-server.c
+++ b/gio/tests/echo-server.c
@@ -7,7 +7,7 @@ int port = 7777;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
diff --git a/gio/tests/fake-service-name.c b/gio/tests/fake-service-name.c
index 1a601a50c..c3a61180c 100644
--- a/gio/tests/fake-service-name.c
+++ b/gio/tests/fake-service-name.c
@@ -51,7 +51,8 @@ incoming_method_call (GDBusConnection *connection,
static const GDBusInterfaceVTable interface_vtable = {
incoming_method_call,
NULL,
- NULL
+ NULL,
+ { 0 }
};
static void
diff --git a/gio/tests/file.c b/gio/tests/file.c
index c8bbed151..2f1b7b310 100644
--- a/gio/tests/file.c
+++ b/gio/tests/file.c
@@ -1,3 +1,4 @@
+#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -174,7 +175,7 @@ typedef struct
gint monitor_deleted;
gint monitor_changed;
gchar *monitor_path;
- gint pos;
+ gsize pos;
const gchar *data;
gchar *buffer;
guint timeout;
@@ -3008,6 +3009,8 @@ test_build_attribute_list_for_copy (void)
int
main (int argc, char *argv[])
{
+ setlocale (LC_ALL, "");
+
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/file/basic", test_basic);
diff --git a/gio/tests/filter-cat.c b/gio/tests/filter-cat.c
index 2cd02b7a2..0bc713735 100644
--- a/gio/tests/filter-cat.c
+++ b/gio/tests/filter-cat.c
@@ -54,7 +54,7 @@ static GOptionEntry entries[] = {
{"to-charset", 0, 0, G_OPTION_ARG_STRING, &to_charset, "to charset", NULL},
{"fallback", 0, 0, G_OPTION_ARG_NONE, &fallback, "use fallback", NULL},
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &locations, "locations", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/tests/filter-streams.c b/gio/tests/filter-streams.c
index e3e67ea18..1f94dc222 100644
--- a/gio/tests/filter-streams.c
+++ b/gio/tests/filter-streams.c
@@ -68,7 +68,7 @@ test_input_filter (void)
gchar buf[1024];
GError *error = NULL;
- g_test_bug ("568394");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=568394");
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
"base-stream", base,
@@ -381,7 +381,6 @@ int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/filter-stream/input", test_input_filter);
g_test_add_func ("/filter-stream/output", test_output_filter);
diff --git a/gio/tests/g-file-info-filesystem-readonly.c b/gio/tests/g-file-info-filesystem-readonly.c
index 16fa83e33..9b94c3220 100644
--- a/gio/tests/g-file-info-filesystem-readonly.c
+++ b/gio/tests/g-file-info-filesystem-readonly.c
@@ -225,8 +225,7 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
- g_test_bug ("787731");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=787731");
g_test_add_data_func ("/g-file-info-filesystem-readonly/test-fs-ro",
GINT_TO_POINTER (FALSE), test_filesystem_readonly);
diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c
index 1a02b5e0e..c11c50462 100644
--- a/gio/tests/g-file-info.c
+++ b/gio/tests/g-file-info.c
@@ -201,6 +201,153 @@ test_g_file_info_modification_time (void)
g_date_time_unref (dt_new_usecs);
}
+static void
+test_g_file_info_access_time (void)
+{
+ GFile *file = NULL;
+ GFileIOStream *io_stream = NULL;
+ GFileInfo *info = NULL;
+ GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
+ *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
+ GTimeSpan ts;
+ GError *error = NULL;
+
+ g_test_summary ("Test that getting the access time of a file works.");
+
+ file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
+ g_assert_no_error (error);
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_TIME_ACCESS,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ g_assert_no_error (error);
+
+ /* Check the access time is retrievable. */
+ dt = g_file_info_get_access_date_time (info);
+ g_assert_nonnull (dt);
+
+ /* Try again with microsecond precision. */
+ g_clear_object (&info);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ g_assert_no_error (error);
+
+ dt_usecs = g_file_info_get_access_date_time (info);
+ g_assert_nonnull (dt_usecs);
+
+ ts = g_date_time_difference (dt_usecs, dt);
+ g_assert_cmpint (ts, >, 0);
+ g_assert_cmpint (ts, <, G_USEC_PER_SEC);
+
+ /* Try round-tripping the access time. */
+ dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
+ g_file_info_set_access_date_time (info, dt_new);
+
+ dt_new_usecs = g_file_info_get_access_date_time (info);
+ ts = g_date_time_difference (dt_new_usecs, dt_new);
+ g_assert_cmpint (ts, ==, 0);
+
+ // try with a negative timestamp
+ dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
+ g_file_info_set_access_date_time (info, dt_before_epoch);
+ dt_before_epoch_returned = g_file_info_get_access_date_time (info);
+ ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
+ g_assert_cmpint (ts, ==, 0);
+
+ /* Clean up. */
+ g_clear_object (&io_stream);
+ g_file_delete (file, NULL, NULL);
+ g_clear_object (&file);
+
+ g_clear_object (&info);
+ g_date_time_unref (dt);
+ g_date_time_unref (dt_usecs);
+ g_date_time_unref (dt_new);
+ g_date_time_unref (dt_new_usecs);
+ g_date_time_unref (dt_before_epoch);
+ g_date_time_unref (dt_before_epoch_returned);
+}
+
+static void
+test_g_file_info_creation_time (void)
+{
+ GFile *file = NULL;
+ GFileIOStream *io_stream = NULL;
+ GFileInfo *info = NULL;
+ GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
+ *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
+ GTimeSpan ts;
+ GError *error = NULL;
+
+ g_test_summary ("Test that getting the creation time of a file works.");
+
+ file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
+ g_assert_no_error (error);
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_TIME_CREATED,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ g_assert_no_error (error);
+
+ /* Check the creation time is retrievable. */
+ dt = g_file_info_get_creation_date_time (info);
+ if (!dt)
+ {
+ g_test_skip ("Skipping testing creation time as it’s not supported by the kernel");
+ g_file_delete (file, NULL, NULL);
+ g_clear_object (&file);
+ g_clear_object (&info);
+ return;
+ }
+
+ /* Try again with microsecond precision. */
+ g_clear_object (&info);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ g_assert_no_error (error);
+
+ dt_usecs = g_file_info_get_creation_date_time (info);
+ g_assert_nonnull (dt_usecs);
+
+ ts = g_date_time_difference (dt_usecs, dt);
+ g_assert_cmpint (ts, >, 0);
+ g_assert_cmpint (ts, <, G_USEC_PER_SEC);
+
+ /* Try round-tripping the creation time. */
+ dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
+ g_file_info_set_creation_date_time (info, dt_new);
+
+ dt_new_usecs = g_file_info_get_creation_date_time (info);
+ ts = g_date_time_difference (dt_new_usecs, dt_new);
+ g_assert_cmpint (ts, ==, 0);
+
+ // try with a negative timestamp
+ dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
+ g_file_info_set_creation_date_time (info, dt_before_epoch);
+ dt_before_epoch_returned = g_file_info_get_creation_date_time (info);
+ ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
+ g_assert_cmpint (ts, ==, 0);
+
+ /* Clean up. */
+ g_clear_object (&io_stream);
+ g_file_delete (file, NULL, NULL);
+ g_clear_object (&file);
+
+ g_clear_object (&info);
+ g_date_time_unref (dt);
+ g_date_time_unref (dt_usecs);
+ g_date_time_unref (dt_new);
+ g_date_time_unref (dt_new_usecs);
+ g_date_time_unref (dt_before_epoch);
+ g_date_time_unref (dt_before_epoch_returned);
+}
+
#ifdef G_OS_WIN32
static void
test_internal_enhanced_stdio (void)
@@ -746,6 +893,8 @@ main (int argc,
g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info);
g_test_add_func ("/g-file-info/test_g_file_info/modification-time", test_g_file_info_modification_time);
+ g_test_add_func ("/g-file-info/test_g_file_info/access-time", test_g_file_info_access_time);
+ g_test_add_func ("/g-file-info/test_g_file_info/creation-time", test_g_file_info_creation_time);
#ifdef G_OS_WIN32
g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio);
#endif
diff --git a/gio/tests/g-file.c b/gio/tests/g-file.c
index f87c1b1d8..8669e3aaf 100644
--- a/gio/tests/g-file.c
+++ b/gio/tests/g-file.c
@@ -111,21 +111,21 @@ test_g_file_new_for_path (void)
{
const struct TestPathsWithOper cmp_paths[] =
{
- {"/", TRUE, 0, "/./"},
- {"//", TRUE, 0, "//"},
- {"//", TRUE, 0, "//./"},
- {"/", TRUE, 0, "/.//"},
- {"/", TRUE, 0, "/././"},
- {"/tmp", TRUE, 0, "/tmp/d/../"},
- {"/", TRUE, 0, "/somedir/../"},
- {"/", FALSE, 0, "/somedir/.../"},
- {"//tmp/dir1", TRUE, 0, "//tmp/dir1"},
- {"/tmp/dir1", TRUE, 0, "///tmp/dir1"},
- {"/tmp/dir1", TRUE, 0, "////tmp/dir1"},
- {"/tmp/dir1", TRUE, 0, "/tmp/./dir1"},
- {"/tmp/dir1", TRUE, 0, "/tmp//dir1"},
- {"/tmp/dir1", TRUE, 0, "/tmp///dir1///"},
- {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, 0, "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/"}
+ {"/", TRUE, 0, "/./", NULL },
+ {"//", TRUE, 0, "//", NULL },
+ {"//", TRUE, 0, "//./", NULL },
+ {"/", TRUE, 0, "/.//", NULL },
+ {"/", TRUE, 0, "/././", NULL },
+ {"/tmp", TRUE, 0, "/tmp/d/../", NULL },
+ {"/", TRUE, 0, "/somedir/../", NULL },
+ {"/", FALSE, 0, "/somedir/.../", NULL },
+ {"//tmp/dir1", TRUE, 0, "//tmp/dir1", NULL },
+ {"/tmp/dir1", TRUE, 0, "///tmp/dir1", NULL },
+ {"/tmp/dir1", TRUE, 0, "////tmp/dir1", NULL },
+ {"/tmp/dir1", TRUE, 0, "/tmp/./dir1", NULL },
+ {"/tmp/dir1", TRUE, 0, "/tmp//dir1", NULL },
+ {"/tmp/dir1", TRUE, 0, "/tmp///dir1///", NULL },
+ {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, 0, "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", NULL }
};
guint i;
@@ -142,19 +142,19 @@ static void
test_g_file_new_for_uri (void)
{
const struct TestPathsWithOper cmp_uris[] = {
- {"file:///", TRUE, 0, "file:///./"},
- {"file:////", TRUE, 0, "file:////"},
- {"file:////", TRUE, 0, "file:////./"},
- {"file:///", TRUE, 0, "file:///.//"},
- {"file:///", TRUE, 0, "file:///././"},
- {"file:///tmp", TRUE, 0, "file:///tmp/d/../"},
- {"file:///", TRUE, 0, "file:///somedir/../"},
- {"file:///", FALSE, 0, "file:///somedir/.../"},
- {"file:////tmp/dir1", TRUE, 0, "file:////tmp/dir1"},
- {"file:///tmp/dir1", TRUE, 0, "file:///tmp/./dir1"},
- {"file:///tmp/dir1", TRUE, 0, "file:///tmp//dir1"},
- {"file:///tmp/dir1", TRUE, 0, "file:///tmp///dir1///"},
- {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, 0, "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/"}
+ {"file:///", TRUE, 0, "file:///./", NULL },
+ {"file:////", TRUE, 0, "file:////", NULL },
+ {"file:////", TRUE, 0, "file:////./", NULL },
+ {"file:///", TRUE, 0, "file:///.//", NULL },
+ {"file:///", TRUE, 0, "file:///././", NULL },
+ {"file:///tmp", TRUE, 0, "file:///tmp/d/../", NULL },
+ {"file:///", TRUE, 0, "file:///somedir/../", NULL },
+ {"file:///", FALSE, 0, "file:///somedir/.../", NULL },
+ {"file:////tmp/dir1", TRUE, 0, "file:////tmp/dir1", NULL },
+ {"file:///tmp/dir1", TRUE, 0, "file:///tmp/./dir1", NULL },
+ {"file:///tmp/dir1", TRUE, 0, "file:///tmp//dir1", NULL },
+ {"file:///tmp/dir1", TRUE, 0, "file:///tmp///dir1///", NULL },
+ {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, 0, "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", NULL }
};
guint i;
@@ -198,11 +198,11 @@ test_g_file_dup (void)
{
const struct TestPathsWithOper dup_paths[] =
{
- {"/", 0, FALSE, ""},
- {"file:///", 0, TRUE, ""},
- {"totalnonsense", 0, FALSE, ""},
- {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, ""},
- {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", 0, TRUE, ""},
+ {"/", 0, FALSE, "", NULL },
+ {"file:///", 0, TRUE, "", NULL },
+ {"totalnonsense", 0, FALSE, "", NULL },
+ {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "", NULL },
+ {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", 0, TRUE, "", NULL },
};
guint i;
@@ -261,11 +261,11 @@ test_g_file_get_parse_name_utf8 (void)
{
const struct TestPathsWithOper strings[] =
{
- {G_DIR_SEPARATOR_S, 0, FALSE, G_DIR_SEPARATOR_S},
- {"file:///", 0, TRUE, G_DIR_SEPARATOR_S},
- {"totalnonsense", 0, FALSE, NULL},
- {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, NULL /* Depends on local file encoding */},
- {"file:///invalid%08/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, TRUE, "file:///invalid%08/UTF-8%20p\xc5\x99\xc3\xadli\xc5\xa1%20\xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd%20k\xc5\xaf\xc5\x88"},
+ {G_DIR_SEPARATOR_S, 0, FALSE, G_DIR_SEPARATOR_S, NULL },
+ {"file:///", 0, TRUE, G_DIR_SEPARATOR_S, NULL },
+ {"totalnonsense", 0, FALSE, NULL, NULL },
+ {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, NULL, NULL /* Depends on local file encoding */},
+ {"file:///invalid%08/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, TRUE, "file:///invalid%08/UTF-8%20p\xc5\x99\xc3\xadli\xc5\xa1%20\xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd%20k\xc5\xaf\xc5\x88", NULL },
};
guint i;
@@ -315,14 +315,14 @@ test_g_file_new_for_commandline_arg (void)
/* TestPathsWithOper.use_uri represents IsURIOnly here */
const struct TestPathsWithOper arg_data[] =
{
- {"./", 0, FALSE, "file"},
- {"../", 0, FALSE, "file"},
- {"/tmp", 0, FALSE, "file"},
- {"//UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "file"},
- {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, FALSE, "file"},
+ {"./", 0, FALSE, "file", NULL },
+ {"../", 0, FALSE, "file", NULL },
+ {"/tmp", 0, FALSE, "file", NULL },
+ {"//UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "file", NULL },
+ {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, FALSE, "file", NULL },
#if 0
- {"http://www.gtk.org/", 0, TRUE, "http"},
- {"ftp://user:pass@ftp.gimp.org/", 0, TRUE, "ftp"},
+ {"http://www.gtk.org/", 0, TRUE, "http", NULL },
+ {"ftp://user:pass@ftp.gimp.org/", 0, TRUE, "ftp", NULL },
#endif
};
GFile *file;
@@ -486,15 +486,15 @@ test_g_file_get_parent_child (void)
const struct TestPathsWithOper paths[] =
{
/* path root_desc uri dir_holder */
- {"/dir1/dir", FALSE, FALSE, "dir"},
- {"/dir", FALSE, FALSE, "dir"},
- {"/", TRUE, FALSE, "dir"},
- {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", FALSE, FALSE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"},
- {"file:///dir1/dir", FALSE, TRUE, "dir"},
- {"file:///dir", FALSE, TRUE, "dir"},
- {"file:///", TRUE, TRUE, "dir"},
- {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", FALSE, TRUE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"},
- {"dav://www.gtk.org/plan/meetings", FALSE, TRUE, "meetings"},
+ {"/dir1/dir", FALSE, FALSE, "dir", NULL },
+ {"/dir", FALSE, FALSE, "dir", NULL },
+ {"/", TRUE, FALSE, "dir", NULL },
+ {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", FALSE, FALSE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL },
+ {"file:///dir1/dir", FALSE, TRUE, "dir", NULL },
+ {"file:///dir", FALSE, TRUE, "dir", NULL },
+ {"file:///", TRUE, TRUE, "dir", NULL },
+ {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", FALSE, TRUE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL },
+ {"dav://www.gtk.org/plan/meetings", FALSE, TRUE, "meetings", NULL },
};
guint i;
diff --git a/gio/tests/gapplication-example-cmdline3.c b/gio/tests/gapplication-example-cmdline3.c
index b95e0cbc8..eecdc6578 100644
--- a/gio/tests/gapplication-example-cmdline3.c
+++ b/gio/tests/gapplication-example-cmdline3.c
@@ -17,7 +17,7 @@ my_cmdline_handler (gpointer data)
{ "arg1", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL },
{ "arg2", 0, 0, G_OPTION_ARG_NONE, &arg2, NULL, NULL },
{ "help", '?', 0, G_OPTION_ARG_NONE, &help, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GError *error;
gint i;
diff --git a/gio/tests/gapplication-example-cmdline4.c b/gio/tests/gapplication-example-cmdline4.c
index 112006212..ece2ee528 100644
--- a/gio/tests/gapplication-example-cmdline4.c
+++ b/gio/tests/gapplication-example-cmdline4.c
@@ -53,7 +53,7 @@ main (int argc, char **argv)
/* A dummy flag option, to be handled in primary */
{ "flag", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "A flag argument", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
app = g_application_new ("org.gtk.TestApplication",
diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c
index 900e7ac97..6f1a27e0f 100644
--- a/gio/tests/gapplication.c
+++ b/gio/tests/gapplication.c
@@ -576,6 +576,81 @@ test_quit (void)
g_free (binpath);
}
+typedef struct
+{
+ gboolean shutdown;
+ GParamSpec *notify_spec; /* (owned) (nullable) */
+} RegisteredData;
+
+static void
+on_registered_shutdown (GApplication *app,
+ gpointer user_data)
+{
+ RegisteredData *registered_data = user_data;
+
+ registered_data->shutdown = TRUE;
+}
+
+static void
+on_registered_notify (GApplication *app,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ RegisteredData *registered_data = user_data;
+ registered_data->notify_spec = g_param_spec_ref (spec);
+
+ if (g_application_get_is_registered (app))
+ g_assert_false (registered_data->shutdown);
+ else
+ g_assert_true (registered_data->shutdown);
+}
+
+static void
+test_registered (void)
+{
+ char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
+ gchar *argv[] = { binpath, NULL };
+ RegisteredData registered_data = { FALSE, NULL };
+ GApplication *app;
+
+ app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE);
+ g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL);
+ g_signal_connect (app, "shutdown", G_CALLBACK (on_registered_shutdown), &registered_data);
+ g_signal_connect (app, "notify::is-registered", G_CALLBACK (on_registered_notify), &registered_data);
+
+ g_assert_null (registered_data.notify_spec);
+
+ g_assert_true (g_application_register (app, NULL, NULL));
+ g_assert_true (g_application_get_is_registered (app));
+
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+
+ g_assert_false (registered_data.shutdown);
+
+ g_application_run (app, 1, argv);
+
+ g_assert_true (registered_data.shutdown);
+ g_assert_false (g_application_get_is_registered (app));
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+
+ /* Register it again */
+ registered_data.shutdown = FALSE;
+ g_assert_true (g_application_register (app, NULL, NULL));
+ g_assert_true (g_application_get_is_registered (app));
+ g_assert_nonnull (registered_data.notify_spec);
+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered");
+ g_clear_pointer (&registered_data.notify_spec, g_param_spec_unref);
+ g_assert_false (registered_data.shutdown);
+
+ g_object_unref (app);
+
+ g_free (binpath);
+}
+
static void
on_activate (GApplication *app)
{
@@ -1136,6 +1211,7 @@ main (int argc, char **argv)
g_test_add_func ("/gapplication/properties", properties);
g_test_add_func ("/gapplication/app-id", appid);
g_test_add_func ("/gapplication/quit", test_quit);
+ g_test_add_func ("/gapplication/registered", test_registered);
g_test_add_func ("/gapplication/local-actions", test_local_actions);
/* g_test_add_func ("/gapplication/remote-actions", test_remote_actions); */
g_test_add_func ("/gapplication/local-command-line", test_local_command_line);
diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c
index 7819e669a..3339e703d 100644
--- a/gio/tests/gdbus-connection-slow.c
+++ b/gio/tests/gdbus-connection-slow.c
@@ -84,7 +84,7 @@ test_connection_flush (void)
for (n = 0; n < 50; n++)
{
gboolean ret;
- gint exit_status;
+ gint wait_status;
guint timeout_mainloop_id;
gchar *flush_helper_stdout = NULL;
gchar *flush_helper_stderr = NULL;
@@ -93,9 +93,9 @@ test_connection_flush (void)
ret = g_spawn_command_line_sync (flush_helper,
&flush_helper_stdout,
&flush_helper_stderr,
- &exit_status,
+ &wait_status,
&error) &&
- g_spawn_check_exit_status (exit_status, &error);
+ g_spawn_check_wait_status (wait_status, &error);
if (!ret)
g_test_message ("Child process ‘%s’ failed. stdout:\n%s\nstderr:\n%s",
flush_helper, flush_helper_stdout, flush_helper_stderr);
diff --git a/gio/tests/gdbus-connection.c b/gio/tests/gdbus-connection.c
index 51dd27f7e..0410a880a 100644
--- a/gio/tests/gdbus-connection.c
+++ b/gio/tests/gdbus-connection.c
@@ -86,7 +86,8 @@ static const GDBusInterfaceVTable boo_vtable =
{
NULL, /* _method_call */
NULL, /* _get_property */
- NULL /* _set_property */
+ NULL, /* _set_property */
+ { 0 }
};
/* Runs in a worker thread. */
diff --git a/gio/tests/gdbus-daemon.c b/gio/tests/gdbus-daemon.c
index a33269916..6c2b81c2c 100644
--- a/gio/tests/gdbus-daemon.c
+++ b/gio/tests/gdbus-daemon.c
@@ -19,7 +19,7 @@ main (int argc, char *argv[])
{ "config-file", 0, 0, G_OPTION_ARG_STRING, &config_file, N_("Ignored, for compat with GTestDbus"), NULL },
{ "print-address", 0, 0, G_OPTION_ARG_NONE, &print_address, N_("Print address"), NULL },
{ "print-env", 0, 0, G_OPTION_ARG_NONE, &print_env, N_("Print address in shell mode"), NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new ("");
diff --git a/gio/tests/gdbus-example-export.c b/gio/tests/gdbus-example-export.c
index f712d88f0..182305068 100644
--- a/gio/tests/gdbus-example-export.c
+++ b/gio/tests/gdbus-example-export.c
@@ -225,7 +225,8 @@ static const GDBusInterfaceVTable interface_vtable =
{
handle_method_call,
handle_get_property,
- handle_set_property
+ handle_set_property,
+ { 0 }
};
static void
diff --git a/gio/tests/gdbus-example-own-name.c b/gio/tests/gdbus-example-own-name.c
index 74d39208f..6c83f12fe 100644
--- a/gio/tests/gdbus-example-own-name.c
+++ b/gio/tests/gdbus-example-own-name.c
@@ -40,7 +40,7 @@ main (int argc, char *argv[])
{ "replace", 'r', 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing name if possible", NULL },
{ "allow-replacement", 'a', 0, G_OPTION_ARG_NONE, &opt_allow_replacement, "Allow replacement", NULL },
{ "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name to acquire", NULL },
- { NULL}
+ G_OPTION_ENTRY_NULL
};
error = NULL;
diff --git a/gio/tests/gdbus-example-peer.c b/gio/tests/gdbus-example-peer.c
index 9d5de32a6..f57d36832 100755
--- a/gio/tests/gdbus-example-peer.c
+++ b/gio/tests/gdbus-example-peer.c
@@ -117,6 +117,7 @@ static const GDBusInterfaceVTable interface_vtable =
handle_method_call,
NULL,
NULL,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
@@ -251,7 +252,7 @@ main (int argc, char *argv[])
{ "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL },
{ "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL },
{ "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL },
- { NULL}
+ G_OPTION_ENTRY_NULL
};
ret = 1;
diff --git a/gio/tests/gdbus-example-server.c b/gio/tests/gdbus-example-server.c
index 00e482724..b19f6505d 100644
--- a/gio/tests/gdbus-example-server.c
+++ b/gio/tests/gdbus-example-server.c
@@ -276,7 +276,8 @@ static const GDBusInterfaceVTable interface_vtable =
{
handle_method_call,
handle_get_property,
- handle_set_property
+ handle_set_property,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/tests/gdbus-example-subtree.c b/gio/tests/gdbus-example-subtree.c
index 714bbe612..3254a27cd 100644
--- a/gio/tests/gdbus-example-subtree.c
+++ b/gio/tests/gdbus-example-subtree.c
@@ -72,7 +72,8 @@ const GDBusInterfaceVTable manager_vtable =
{
manager_method_call,
NULL, /* get_property */
- NULL /* set_property */
+ NULL, /* set_property */
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
@@ -187,6 +188,7 @@ const GDBusInterfaceVTable block_vtable =
block_method_call,
block_get_property,
block_set_property,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
@@ -223,8 +225,9 @@ partition_method_call (GDBusConnection *connection,
const GDBusInterfaceVTable partition_vtable =
{
partition_method_call,
- //partition_get_property,
- //partition_set_property
+ NULL,
+ NULL,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
@@ -321,7 +324,8 @@ const GDBusSubtreeVTable subtree_vtable =
{
subtree_enumerate,
subtree_introspect,
- subtree_dispatch
+ subtree_dispatch,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/tests/gdbus-example-watch-name.c b/gio/tests/gdbus-example-watch-name.c
index caec6ec08..27cc3f387 100644
--- a/gio/tests/gdbus-example-watch-name.c
+++ b/gio/tests/gdbus-example-watch-name.c
@@ -9,7 +9,7 @@ static GOptionEntry opt_entries[] =
{ "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name to watch", NULL },
{ "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL },
{ "auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_auto_start, "Instruct the bus to launch an owner for the name", NULL},
- { NULL}
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/tests/gdbus-example-watch-proxy.c b/gio/tests/gdbus-example-watch-proxy.c
index 51132e385..8cce90c0d 100644
--- a/gio/tests/gdbus-example-watch-proxy.c
+++ b/gio/tests/gdbus-example-watch-proxy.c
@@ -15,7 +15,7 @@ static GOptionEntry opt_entries[] =
{ "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL },
{ "no-auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_no_auto_start, "Don't instruct the bus to launch an owner for the name", NULL},
{ "no-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_no_properties, "Do not load properties", NULL},
- { NULL}
+ G_OPTION_ENTRY_NULL
};
static GMainLoop *loop = NULL;
diff --git a/gio/tests/gdbus-exit-on-close.c b/gio/tests/gdbus-exit-on-close.c
index 4241fc7a4..1bf0ce7dd 100644
--- a/gio/tests/gdbus-exit-on-close.c
+++ b/gio/tests/gdbus-exit-on-close.c
@@ -49,7 +49,7 @@ static const TestData cases[] = {
{ "true", NULL, EXPLICITLY_TRUE, REMOTE },
{ "false", NULL, EXPLICITLY_FALSE, REMOTE },
{ "we-close", "662100", EXPLICITLY_TRUE, LOCAL },
- { NULL }
+ { NULL, NULL, 0, 0 }
};
static gboolean
diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
index 61d47e90a..aec21d7d0 100644
--- a/gio/tests/gdbus-export.c
+++ b/gio/tests/gdbus-export.c
@@ -127,6 +127,8 @@ static const GDBusInterfaceInfo foo2_interface_info =
"org.example.Foo2",
(GDBusMethodInfo **) &foo_method_info_pointers,
(GDBusSignalInfo **) &foo_signal_info_pointers,
+ NULL,
+ NULL
};
static void
@@ -198,7 +200,8 @@ static const GDBusInterfaceVTable foo_vtable =
{
foo_method_call,
foo_get_property,
- foo_set_property
+ foo_set_property,
+ { 0 },
};
/* -------------------- */
@@ -311,7 +314,8 @@ static const GDBusInterfaceVTable dyna_interface_vtable =
{
dyna_cyber,
NULL,
- NULL
+ NULL,
+ { 0 }
};
/* ---------------------------------------------------------------------------------------------------- */
@@ -693,7 +697,8 @@ static const GDBusSubtreeVTable subtree_vtable =
{
subtree_enumerate,
subtree_introspect,
- subtree_dispatch
+ subtree_dispatch,
+ { 0 }
};
/* -------------------- */
@@ -747,7 +752,8 @@ static const GDBusSubtreeVTable dynamic_subtree_vtable =
{
dynamic_subtree_enumerate,
dynamic_subtree_introspect,
- dynamic_subtree_dispatch
+ dynamic_subtree_dispatch,
+ { 0 }
};
/* -------------------- */
@@ -1729,7 +1735,7 @@ test_async_properties (void)
GError *error = NULL;
guint registration_id, registration_id2;
static const GDBusInterfaceVTable vtable = {
- test_async_method_call, NULL, NULL
+ test_async_method_call, NULL, NULL, { 0 }
};
c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
diff --git a/gio/tests/gdbus-names.c b/gio/tests/gdbus-names.c
index 05d2015d0..8504220a9 100644
--- a/gio/tests/gdbus-names.c
+++ b/gio/tests/gdbus-names.c
@@ -1,6 +1,7 @@
/* GLib testing framework examples and tests
*
* Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2021 Frederic Martinsons
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,6 +17,7 @@
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: David Zeuthen <davidz@redhat.com>
+ * Author: Frederic Martinsons <frederic.martinsons@gmail.com>
*/
#include <gio/gio.h>
@@ -495,6 +497,20 @@ typedef struct
guint num_free_func;
} WatchNameData;
+typedef struct
+{
+ WatchNameData data;
+ GDBusConnection *connection;
+ GMutex cond_mutex;
+ GCond cond;
+ gboolean started;
+ gboolean name_acquired;
+ gboolean ended;
+ gboolean unwatch_early;
+ GMutex mutex;
+ guint watch_id;
+} WatchNameThreadData;
+
static void
watch_name_data_free_func (WatchNameData *data)
{
@@ -514,7 +530,7 @@ w_name_acquired_handler (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
- WatchNameData *data = user_data;
+ OwnNameData *data = user_data;
data->num_acquired += 1;
g_main_loop_quit (loop);
}
@@ -524,7 +540,7 @@ w_name_lost_handler (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
- WatchNameData *data = user_data;
+ OwnNameData *data = user_data;
data->num_lost += 1;
g_main_loop_quit (loop);
}
@@ -613,6 +629,7 @@ stop_service (GDBusConnection *connection,
{
GError *error = NULL;
GDBusProxy *proxy = NULL;
+ GVariant *result = NULL;
data->num_vanished = 0;
@@ -626,15 +643,17 @@ stop_service (GDBusConnection *connection,
&error);
g_assert_no_error (error);
- g_dbus_proxy_call_sync (proxy,
- "Quit",
- NULL,
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- 100,
- NULL,
- &error);
+ result = g_dbus_proxy_call_sync (proxy,
+ "Quit",
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ 100,
+ NULL,
+ &error);
g_assert_no_error (error);
g_object_unref (proxy);
+ if (result)
+ g_variant_unref (result);
while (data->num_vanished == 0)
g_main_loop_run (loop);
}
@@ -643,6 +662,7 @@ static void
test_bus_watch_name (gconstpointer d)
{
WatchNameData data;
+ OwnNameData own_data;
guint id;
guint owner_id;
GDBusConnection *connection;
@@ -685,15 +705,16 @@ test_bus_watch_name (gconstpointer d)
g_assert_cmpint (data.num_appeared, ==, 0);
g_assert_cmpint (data.num_vanished, ==, 1);
g_assert_cmpint (data.num_free_func, ==, 1);
+ data.num_free_func = 0;
/*
* Now bring up a bus, own a name, and then start watching it.
*/
session_bus_up ();
/* own the name */
- data.num_free_func = 0;
- data.num_acquired = 0;
- data.num_lost = 0;
+ own_data.num_free_func = 0;
+ own_data.num_acquired = 0;
+ own_data.num_lost = 0;
data.expect_null_connection = FALSE;
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
name,
@@ -701,11 +722,11 @@ test_bus_watch_name (gconstpointer d)
w_bus_acquired_handler,
w_name_acquired_handler,
w_name_lost_handler,
- &data,
- (GDestroyNotify) watch_name_data_free_func);
+ &own_data,
+ (GDestroyNotify) own_name_data_free_func);
g_main_loop_run (loop);
- g_assert_cmpint (data.num_acquired, ==, 1);
- g_assert_cmpint (data.num_lost, ==, 0);
+ g_assert_cmpint (own_data.num_acquired, ==, 1);
+ g_assert_cmpint (own_data.num_lost, ==, 0);
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
g_assert (connection != NULL);
@@ -750,9 +771,9 @@ test_bus_watch_name (gconstpointer d)
/* unown the name */
g_bus_unown_name (owner_id);
g_main_loop_run (loop);
- g_assert_cmpint (data.num_acquired, ==, 1);
- g_assert_cmpint (data.num_free_func, ==, 2);
-
+ g_assert_cmpint (own_data.num_acquired, ==, 1);
+ g_assert_cmpint (own_data.num_free_func, ==, 1);
+ own_data.num_free_func = 0;
/*
* Create a watcher and then make a name be owned.
*
@@ -802,21 +823,21 @@ test_bus_watch_name (gconstpointer d)
if (!watch_name_test->existing_service)
{
/* own the name */
- data.num_acquired = 0;
- data.num_lost = 0;
- data.expect_null_connection = FALSE;
+ own_data.num_acquired = 0;
+ own_data.num_lost = 0;
+ own_data.expect_null_connection = FALSE;
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
name,
G_BUS_NAME_OWNER_FLAGS_NONE,
w_bus_acquired_handler,
w_name_acquired_handler,
w_name_lost_handler,
- &data,
- (GDestroyNotify) watch_name_data_free_func);
- while (data.num_acquired == 0 || data.num_appeared == 0)
+ &own_data,
+ (GDestroyNotify) own_name_data_free_func);
+ while (own_data.num_acquired == 0 || data.num_appeared == 0)
g_main_loop_run (loop);
- g_assert_cmpint (data.num_acquired, ==, 1);
- g_assert_cmpint (data.num_lost, ==, 0);
+ g_assert_cmpint (own_data.num_acquired, ==, 1);
+ g_assert_cmpint (own_data.num_lost, ==, 0);
g_assert_cmpint (data.num_appeared, ==, 1);
g_assert_cmpint (data.num_vanished, ==, 1);
}
@@ -835,12 +856,12 @@ test_bus_watch_name (gconstpointer d)
if (!watch_name_test->existing_service)
{
g_main_loop_run (loop);
- g_assert_cmpint (data.num_lost, ==, 1);
+ g_assert_cmpint (own_data.num_lost, ==, 1);
g_assert_cmpint (data.num_vanished, ==, 2);
}
else
{
- g_assert_cmpint (data.num_lost, ==, 0);
+ g_assert_cmpint (own_data.num_lost, ==, 0);
g_assert_cmpint (data.num_vanished, ==, 1);
}
g_bus_unwatch_name (id);
@@ -850,11 +871,253 @@ test_bus_watch_name (gconstpointer d)
{
g_bus_unown_name (owner_id);
g_main_loop_run (loop);
- g_assert_cmpint (data.num_free_func, ==, 2);
+ g_assert_cmpint (own_data.num_free_func, ==, 1);
+ }
+ session_bus_down ();
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/* Called in the same thread as watcher_thread() */
+static void
+t_watch_name_data_free_func (WatchNameThreadData *thread_data)
+{
+ thread_data->data.num_free_func++;
+}
+
+/* Called in the same thread as watcher_thread() */
+static void
+t_name_appeared_handler (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ WatchNameThreadData *thread_data = user_data;
+ thread_data->data.num_appeared += 1;
+}
+
+/* Called in the same thread as watcher_thread() */
+static void
+t_name_vanished_handler (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ WatchNameThreadData *thread_data = user_data;
+ thread_data->data.num_vanished += 1;
+}
+
+/* Called in the thread which constructed the GDBusConnection */
+static void
+connection_closed_cb (GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ gpointer user_data)
+{
+ WatchNameThreadData *thread_data = (WatchNameThreadData *) user_data;
+ if (thread_data->unwatch_early)
+ {
+ g_mutex_lock (&thread_data->mutex);
+ g_bus_unwatch_name (g_atomic_int_get (&thread_data->watch_id));
+ g_atomic_int_set (&thread_data->watch_id, 0);
+ g_cond_signal (&thread_data->cond);
+ g_mutex_unlock (&thread_data->mutex);
}
+}
+
+static gpointer
+watcher_thread (gpointer user_data)
+{
+ WatchNameThreadData *thread_data = user_data;
+ GMainContext *thread_context;
+
+ thread_context = g_main_context_new ();
+ g_main_context_push_thread_default (thread_context);
+
+ // Notify that the thread has started
+ g_mutex_lock (&thread_data->cond_mutex);
+ g_atomic_int_set (&thread_data->started, TRUE);
+ g_cond_signal (&thread_data->cond);
+ g_mutex_unlock (&thread_data->cond_mutex);
+
+ // Wait for the main thread to own the name before watching it
+ g_mutex_lock (&thread_data->cond_mutex);
+ while (!g_atomic_int_get (&thread_data->name_acquired))
+ g_cond_wait (&thread_data->cond, &thread_data->cond_mutex);
+ g_mutex_unlock (&thread_data->cond_mutex);
+
+ thread_data->data.num_appeared = 0;
+ thread_data->data.num_vanished = 0;
+ thread_data->data.num_free_func = 0;
+ // g_signal_connect_after is important to have default handler be called before our code
+ g_signal_connect_after (thread_data->connection, "closed", G_CALLBACK (connection_closed_cb), thread_data);
+
+ g_mutex_lock (&thread_data->mutex);
+ thread_data->watch_id = g_bus_watch_name_on_connection (thread_data->connection,
+ "org.gtk.GDBus.Name1",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ t_name_appeared_handler,
+ t_name_vanished_handler,
+ thread_data,
+ (GDestroyNotify) t_watch_name_data_free_func);
+ g_mutex_unlock (&thread_data->mutex);
+
+ g_assert_cmpint (thread_data->data.num_appeared, ==, 0);
+ g_assert_cmpint (thread_data->data.num_vanished, ==, 0);
+ while (thread_data->data.num_appeared == 0)
+ g_main_context_iteration (thread_context, TRUE);
+ g_assert_cmpint (thread_data->data.num_appeared, ==, 1);
+ g_assert_cmpint (thread_data->data.num_vanished, ==, 0);
+ thread_data->data.num_appeared = 0;
+
+ /* Close the connection and:
+ * - check that we had received a vanished event even begin in different thread
+ * - or check that unwatching the bus when a vanished had been scheduled
+ * make it correctly unscheduled (unwatch_early condition)
+ */
+ g_dbus_connection_close_sync (thread_data->connection, NULL, NULL);
+ if (thread_data->unwatch_early)
+ {
+ // Wait for the main thread to iterate in order to have close connection handled
+ g_mutex_lock (&thread_data->mutex);
+ while (g_atomic_int_get (&thread_data->watch_id) != 0)
+ g_cond_wait (&thread_data->cond, &thread_data->mutex);
+ g_mutex_unlock (&thread_data->mutex);
+
+ while (thread_data->data.num_free_func == 0)
+ g_main_context_iteration (thread_context, TRUE);
+ g_assert_cmpint (thread_data->data.num_vanished, ==, 0);
+ g_assert_cmpint (thread_data->data.num_appeared, ==, 0);
+ g_assert_cmpint (thread_data->data.num_free_func, ==, 1);
+ }
+ else
+ {
+ while (thread_data->data.num_vanished == 0)
+ {
+ /*
+ * Close of connection is treated in the context of the thread which
+ * creates the connection. We must run iteration on it (to have the 'closed'
+ * signal handled) and also run current thread loop to have name_vanished
+ * callback handled.
+ */
+ g_main_context_iteration (thread_context, TRUE);
+ }
+ g_assert_cmpint (thread_data->data.num_vanished, ==, 1);
+ g_assert_cmpint (thread_data->data.num_appeared, ==, 0);
+ g_mutex_lock (&thread_data->mutex);
+ g_bus_unwatch_name (g_atomic_int_get (&thread_data->watch_id));
+ g_atomic_int_set (&thread_data->watch_id, 0);
+ g_mutex_unlock (&thread_data->mutex);
+ while (thread_data->data.num_free_func == 0)
+ g_main_context_iteration (thread_context, TRUE);
+ g_assert_cmpint (thread_data->data.num_free_func, ==, 1);
+ }
+
+ g_mutex_lock (&thread_data->cond_mutex);
+ thread_data->ended = TRUE;
+ g_main_context_wakeup (NULL);
+ g_cond_signal (&thread_data->cond);
+ g_mutex_unlock (&thread_data->cond_mutex);
+
+ g_signal_handlers_disconnect_by_func (thread_data->connection, connection_closed_cb, thread_data);
+ g_object_unref (thread_data->connection);
+ g_main_context_pop_thread_default (thread_context);
+ g_main_context_unref (thread_context);
+
+ g_mutex_lock (&thread_data->mutex);
+ g_assert_cmpint (thread_data->watch_id, ==, 0);
+ g_mutex_unlock (&thread_data->mutex);
+ return NULL;
+}
+
+static void
+watch_with_different_context (gboolean unwatch_early)
+{
+ OwnNameData own_data;
+ WatchNameThreadData thread_data;
+ GDBusConnection *connection;
+ GThread *watcher;
+ guint id;
+
+ session_bus_up ();
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ g_assert (connection != NULL);
+
+ g_mutex_init (&thread_data.mutex);
+ g_mutex_init (&thread_data.cond_mutex);
+ g_cond_init (&thread_data.cond);
+ thread_data.started = FALSE;
+ thread_data.name_acquired = FALSE;
+ thread_data.ended = FALSE;
+ thread_data.connection = g_object_ref (connection);
+ thread_data.unwatch_early = unwatch_early;
+
+ // Create a thread which will watch a name and wait for it to be ready
+ g_mutex_lock (&thread_data.cond_mutex);
+ watcher = g_thread_new ("watcher", watcher_thread, &thread_data);
+ while (!g_atomic_int_get (&thread_data.started))
+ g_cond_wait (&thread_data.cond, &thread_data.cond_mutex);
+ g_mutex_unlock (&thread_data.cond_mutex);
+
+ own_data.num_acquired = 0;
+ own_data.num_lost = 0;
+ own_data.num_free_func = 0;
+ own_data.expect_null_connection = FALSE;
+ // Own the name to avoid direct name vanished in watcher thread
+ id = g_bus_own_name_on_connection (connection,
+ "org.gtk.GDBus.Name1",
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ w_name_acquired_handler,
+ w_name_lost_handler,
+ &own_data,
+ (GDestroyNotify) own_name_data_free_func);
+ while (own_data.num_acquired == 0)
+ g_main_context_iteration (NULL, TRUE);
+ g_assert_cmpint (own_data.num_acquired, ==, 1);
+ g_assert_cmpint (own_data.num_lost, ==, 0);
+
+ // Wake the thread for it to begin watch
+ g_mutex_lock (&thread_data.cond_mutex);
+ g_atomic_int_set (&thread_data.name_acquired, TRUE);
+ g_cond_signal (&thread_data.cond);
+ g_mutex_unlock (&thread_data.cond_mutex);
+
+ // Iterate the loop until thread is waking us up
+ while (!thread_data.ended)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_thread_join (watcher);
+
+ g_bus_unown_name (id);
+ while (own_data.num_free_func == 0)
+ g_main_context_iteration (NULL, TRUE);
+ g_assert_cmpint (own_data.num_free_func, ==, 1);
+
+ g_mutex_clear (&thread_data.mutex);
+ g_mutex_clear (&thread_data.cond_mutex);
+ g_cond_clear (&thread_data.cond);
+
+ session_bus_stop ();
+ g_assert_true (g_dbus_connection_is_closed (connection));
+ g_object_unref (connection);
session_bus_down ();
}
+static void
+test_bus_watch_different_context (void)
+{
+ watch_with_different_context (FALSE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+test_bus_unwatch_early (void)
+{
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/604");
+ watch_with_different_context (TRUE);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -899,9 +1162,15 @@ test_validate_names (void)
g_assert (!g_dbus_is_unique_name (names[n].string));
if (names[n].interface)
- g_assert (g_dbus_is_interface_name (names[n].string));
+ {
+ g_assert (g_dbus_is_interface_name (names[n].string));
+ g_assert (g_dbus_is_error_name (names[n].string));
+ }
else
- g_assert (!g_dbus_is_interface_name (names[n].string));
+ {
+ g_assert (!g_dbus_is_interface_name (names[n].string));
+ g_assert (!g_dbus_is_error_name (names[n].string));
+ }
}
}
@@ -979,6 +1248,8 @@ main (int argc,
g_test_add_data_func ("/gdbus/bus-watch-name-closures-auto-start",
&watch_closures_flags_auto_start,
test_bus_watch_name);
+ g_test_add_func ("/gdbus/bus-watch-different-context", test_bus_watch_different_context);
+ g_test_add_func ("/gdbus/bus-unwatch-early", test_bus_unwatch_early);
g_test_add_func ("/gdbus/escape-object-path", test_escape_object_path);
ret = g_test_run();
diff --git a/gio/tests/gdbus-non-socket.c b/gio/tests/gdbus-non-socket.c
index 64d985a15..911aff262 100644
--- a/gio/tests/gdbus-non-socket.c
+++ b/gio/tests/gdbus-non-socket.c
@@ -112,7 +112,8 @@ pokee_method_call (GDBusConnection *connection,
static const GDBusInterfaceVTable pokee_vtable = {
pokee_method_call,
NULL, /* get_property */
- NULL /* set_property */
+ NULL, /* set_property */
+ { 0 }
};
/* Processes:
diff --git a/gio/tests/gdbus-peer-object-manager.c b/gio/tests/gdbus-peer-object-manager.c
index 676c9f080..f101b46bd 100644
--- a/gio/tests/gdbus-peer-object-manager.c
+++ b/gio/tests/gdbus-peer-object-manager.c
@@ -108,6 +108,7 @@ mock_interface_get_vtable (GDBusInterfaceSkeleton *interface)
NULL,
mock_interface_get_property,
NULL,
+ { 0 }
};
return &vtable;
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 34fab5713..2f2caf77a 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -258,7 +258,8 @@ static const GDBusInterfaceVTable test_interface_vtable =
{
test_interface_method_call,
test_interface_get_property,
- NULL /* set_property */
+ NULL, /* set_property */
+ { 0 }
};
static void
@@ -1436,7 +1437,8 @@ static const GDBusInterfaceVTable dmp_interface_vtable =
{
dmp_on_method_call,
NULL, /* get_property */
- NULL /* set_property */
+ NULL, /* set_property */
+ { 0 }
};
diff --git a/gio/tests/gdbus-proxy.c b/gio/tests/gdbus-proxy.c
index a2160dcca..7e619c2ac 100644
--- a/gio/tests/gdbus-proxy.c
+++ b/gio/tests/gdbus-proxy.c
@@ -132,7 +132,7 @@ test_methods (GDBusProxy *proxy)
static gboolean
strv_equal (gchar **strv, ...)
{
- gint count;
+ gsize count;
va_list list;
const gchar *str;
gboolean res;
diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c
index b95244c9a..a3b03c5e0 100644
--- a/gio/tests/gdbus-serialization.c
+++ b/gio/tests/gdbus-serialization.c
@@ -1051,7 +1051,7 @@ test_message_parse_empty_arrays_of_arrays (void)
GVariant *body;
GError *error = NULL;
- g_test_bug ("673612");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=673612");
/* These three-element array of empty arrays were previously read back as a
* two-element array of empty arrays, due to sometimes erroneously skipping
* four bytes to align for the eight-byte-aligned grandchild types (x and
@@ -1107,7 +1107,7 @@ test_message_serialize_double_array (void)
GVariantBuilder builder;
GVariant *body;
- g_test_bug ("732754");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=732754");
g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad"));
g_variant_builder_add (&builder, "d", (gdouble)0.0);
@@ -1480,7 +1480,6 @@ main (int argc,
setlocale (LC_ALL, "C");
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
g_test_add_func ("/gdbus/message-serialize/basic",
test_message_serialize_basic);
diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c
index 36be37b72..0681e7ec8 100644
--- a/gio/tests/gdbus-test-codegen.c
+++ b/gio/tests/gdbus-test-codegen.c
@@ -1920,7 +1920,7 @@ check_object_manager (void)
GError *error;
GMainLoop *loop;
OMData *om_data = NULL;
- guint om_signal_id = -1;
+ guint om_signal_id = 0;
GDBusObjectManager *pm = NULL;
GList *object_proxies;
GList *proxies;
@@ -2356,7 +2356,7 @@ check_object_manager (void)
if (loop != NULL)
g_main_loop_unref (loop);
- if (om_signal_id != -1)
+ if (om_signal_id != 0)
g_dbus_connection_signal_unsubscribe (c, om_signal_id);
g_clear_object (&o3);
g_clear_object (&o2);
diff --git a/gio/tests/gdbus-testserver.c b/gio/tests/gdbus-testserver.c
index dd0d5ba5a..ae8e47b18 100644
--- a/gio/tests/gdbus-testserver.c
+++ b/gio/tests/gdbus-testserver.c
@@ -322,7 +322,7 @@ handle_method_call (GDBusConnection *connection,
const guint64 *uint64s;
const gdouble *doubles;
gsize n_elts;
- gint i, j;
+ gsize i, j;
GVariantBuilder ret;
g_variant_builder_init (&ret, G_VARIANT_TYPE ("(ayabanaqaiauaxatad)"));
@@ -802,7 +802,8 @@ static const GDBusInterfaceVTable interface_vtable =
{
handle_method_call,
handle_get_property,
- handle_set_property
+ handle_set_property,
+ { 0 }
};
static void
diff --git a/gio/tests/glistmodel.c b/gio/tests/glistmodel.c
index 5ecf45f79..e50969ead 100644
--- a/gio/tests/glistmodel.c
+++ b/gio/tests/glistmodel.c
@@ -270,7 +270,7 @@ test_store_splice_replace_middle (void)
GAction *item;
GPtrArray *array;
- g_test_bug ("795307");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307");
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
@@ -326,7 +326,7 @@ test_store_splice_replace_all (void)
GPtrArray *array;
GAction *item;
- g_test_bug ("795307");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307");
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
@@ -874,7 +874,6 @@ test_store_find (void)
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/");
g_test_add_func ("/glistmodel/store/properties", test_store_properties);
g_test_add_func ("/glistmodel/store/non-gobjects", test_store_non_gobjects);
diff --git a/gio/tests/gnotification-server.c b/gio/tests/gnotification-server.c
index 9585b0949..c98cbf018 100644
--- a/gio/tests/gnotification-server.c
+++ b/gio/tests/gnotification-server.c
@@ -220,7 +220,7 @@ g_notification_server_bus_acquired (GDBusConnection *connection,
gpointer user_data)
{
const GDBusInterfaceVTable vtable = {
- org_gtk_Notifications_method_call, NULL, NULL
+ org_gtk_Notifications_method_call, NULL, NULL, { 0 }
};
GNotificationServer *server = user_data;
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index 9e570a1b2..42eeccd7a 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -2397,7 +2397,7 @@ strv_has_string (gchar **haystack,
static gboolean
strv_set_equal (gchar **strv, ...)
{
- gint count;
+ gsize count;
va_list list;
const gchar *str;
gboolean res;
@@ -2572,7 +2572,7 @@ test_schema_source (void)
GSettingsBackend *backend;
GSettingsSchema *schema;
GError *error = NULL;
- GSettings *settings;
+ GSettings *settings, *child;
gboolean enabled;
backend = g_settings_backend_get_default ();
@@ -2628,13 +2628,18 @@ test_schema_source (void)
g_assert_nonnull (schema);
/* try to use it for something */
- settings = g_settings_new_full (schema, backend, g_settings_schema_get_path (schema));
+ settings = g_settings_new_full (schema, backend, "/test/");
g_settings_schema_unref (schema);
enabled = FALSE;
g_settings_get (settings, "enabled", "b", &enabled);
g_assert_true (enabled);
- g_object_unref (settings);
+ /* Check that child schemas are resolved from the correct schema source, see glib#1884 */
+ child = g_settings_get_child (settings, "child");
+ g_settings_get (settings, "enabled", "b", &enabled);
+
+ g_object_unref (child);
+ g_object_unref (settings);
g_settings_schema_source_unref (source);
/* try again, but with no parent */
diff --git a/gio/tests/gsubprocess-testprog.c b/gio/tests/gsubprocess-testprog.c
index c9b06c2a2..da3cf8d00 100644
--- a/gio/tests/gsubprocess-testprog.c
+++ b/gio/tests/gsubprocess-testprog.c
@@ -12,7 +12,7 @@
#endif
static GOptionEntry options[] = {
- {NULL}
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c
index 7e22678ec..084b77df3 100644
--- a/gio/tests/gsubprocess.c
+++ b/gio/tests/gsubprocess.c
@@ -233,7 +233,7 @@ test_exit1_cancel (void)
GSubprocess *proc;
TestExit1CancelData data = { 0 };
- g_test_bug ("786456");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=786456");
args = get_test_subprocess_args ("exit1", NULL);
proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
@@ -288,7 +288,7 @@ test_exit1_cancel_in_cb (void)
GSubprocess *proc;
TestExit1CancelData data = { 0 };
- g_test_bug ("786456");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=786456");
args = get_test_subprocess_args ("exit1", NULL);
proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
@@ -611,7 +611,7 @@ on_subprocess_exited (GObject *object,
g_propagate_error (&data->error, error);
}
}
- g_spawn_check_exit_status (g_subprocess_get_exit_status (subprocess), &error);
+ g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error);
g_assert_no_error (error);
data->events_pending--;
if (data->events_pending == 0)
@@ -771,7 +771,7 @@ test_communicate_async (gconstpointer test_data)
GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
GError *error = NULL;
GPtrArray *args;
- TestAsyncCommunicateData data = { flags, 0, };
+ TestAsyncCommunicateData data = { flags, 0, 0, NULL };
GSubprocess *proc;
GCancellable *cancellable = NULL;
GBytes *input;
@@ -1022,7 +1022,7 @@ test_communicate_utf8_async (gconstpointer test_data)
GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
GError *error = NULL;
GPtrArray *args;
- TestAsyncCommunicateData data = { flags, 0, };
+ TestAsyncCommunicateData data = { flags, 0, 0, NULL };
GSubprocess *proc;
GCancellable *cancellable = NULL;
@@ -1055,7 +1055,7 @@ test_communicate_utf8_cancelled_async (gconstpointer test_data)
GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
GError *error = NULL;
GPtrArray *args;
- TestAsyncCommunicateData data = { flags, 0, };
+ TestAsyncCommunicateData data = { flags, 0, 0, NULL };
GSubprocess *proc;
GCancellable *cancellable = NULL;
@@ -1199,7 +1199,7 @@ test_communicate_utf8_async_invalid (void)
GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_PIPE;
GError *error = NULL;
GPtrArray *args;
- TestAsyncCommunicateData data = { flags, 0, };
+ TestAsyncCommunicateData data = { flags, 0, 0, NULL };
GSubprocess *proc;
GCancellable *cancellable = NULL;
@@ -1281,7 +1281,7 @@ on_request_quit_exited (GObject *object,
g_assert_true (g_subprocess_get_if_signaled (subprocess));
g_assert_cmpint (g_subprocess_get_term_sig (subprocess), ==, 9);
#endif
- g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
+ g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error);
g_assert_nonnull (error);
g_clear_error (&error);
@@ -1812,7 +1812,6 @@ main (int argc, char **argv)
gsize i;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/");
g_test_add_func ("/gsubprocess/noop", test_noop);
g_test_add_func ("/gsubprocess/noop-all-to-null", test_noop_all_to_null);
diff --git a/gio/tests/gtesttlsbackend.c b/gio/tests/gtesttlsbackend.c
index 56d155031..6c48c2394 100644
--- a/gio/tests/gtesttlsbackend.c
+++ b/gio/tests/gtesttlsbackend.c
@@ -110,6 +110,12 @@ enum
PROP_CERT_ISSUER,
PROP_CERT_PKCS11_URI,
PROP_CERT_PRIVATE_KEY_PKCS11_URI,
+ PROP_CERT_NOT_VALID_BEFORE,
+ PROP_CERT_NOT_VALID_AFTER,
+ PROP_CERT_SUBJECT_NAME,
+ PROP_CERT_ISSUER_NAME,
+ PROP_CERT_DNS_NAMES,
+ PROP_CERT_IP_ADDRESSES,
};
static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface);
@@ -135,6 +141,8 @@ g_test_tls_certificate_get_property (GObject *object,
GParamSpec *pspec)
{
GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
+ GPtrArray *data = NULL;
+ const gchar *dns_name = "a.example.com";
switch (prop_id)
{
@@ -156,6 +164,28 @@ g_test_tls_certificate_get_property (GObject *object,
case PROP_CERT_PRIVATE_KEY_PKCS11_URI:
g_value_set_string (value, cert->private_key_pkcs11_uri);
break;
+ case PROP_CERT_NOT_VALID_BEFORE:
+ g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2020-10-12T17:49:44Z", NULL));
+ break;
+ case PROP_CERT_NOT_VALID_AFTER:
+ g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2045-10-06T17:49:44Z", NULL));
+ break;
+ case PROP_CERT_SUBJECT_NAME:
+ g_value_set_string (value, "DC=COM,DC=EXAMPLE,CN=server.example.com");
+ break;
+ case PROP_CERT_ISSUER_NAME:
+ g_value_set_string (value, "DC=COM,DC=EXAMPLE,OU=Certificate Authority,CN=ca.example.com,emailAddress=ca@example.com");
+ break;
+ case PROP_CERT_DNS_NAMES:
+ data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
+ g_ptr_array_add (data, g_bytes_new_static (dns_name, strlen (dns_name)));
+ g_value_take_boxed (value, data);
+ break;
+ case PROP_CERT_IP_ADDRESSES:
+ data = g_ptr_array_new_with_free_func (g_object_unref);
+ g_ptr_array_add (data, g_inet_address_new_from_string ("192.0.2.1"));
+ g_value_take_boxed (value, data);
+ break;
default:
g_assert_not_reached ();
break;
@@ -230,6 +260,12 @@ g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer");
g_object_class_override_property (gobject_class, PROP_CERT_PKCS11_URI, "pkcs11-uri");
g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PKCS11_URI, "private-key-pkcs11-uri");
+ g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_BEFORE, "not-valid-before");
+ g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_AFTER, "not-valid-after");
+ g_object_class_override_property (gobject_class, PROP_CERT_SUBJECT_NAME, "subject-name");
+ g_object_class_override_property (gobject_class, PROP_CERT_ISSUER_NAME, "issuer-name");
+ g_object_class_override_property (gobject_class, PROP_CERT_DNS_NAMES, "dns-names");
+ g_object_class_override_property (gobject_class, PROP_CERT_IP_ADDRESSES, "ip-addresses");
}
static void
@@ -371,12 +407,6 @@ g_test_tls_connection_initable_iface_init (GInitableIface *iface)
iface->init = g_test_tls_connection_initable_init;
}
-const gchar *
-g_test_tls_connection_get_private_key_pem (GTlsCertificate *cert)
-{
- return ((GTestTlsCertificate *)cert)->key_pem;
-}
-
/* Test database type */
typedef struct _GTestTlsDatabase GTestTlsDatabase;
diff --git a/gio/tests/gtesttlsbackend.h b/gio/tests/gtesttlsbackend.h
index 11a8bf149..07948fddc 100644
--- a/gio/tests/gtesttlsbackend.h
+++ b/gio/tests/gtesttlsbackend.h
@@ -39,9 +39,6 @@ struct _GTestTlsBackendClass {
GType _g_test_tls_backend_get_type (void);
-const gchar *g_test_tls_connection_get_private_key_pem (GTlsCertificate *cert);
-
-
G_END_DECLS
#endif /* __G_TEST_TLS_BACKEND_H__ */
diff --git a/gio/tests/httpd.c b/gio/tests/httpd.c
index 9bca6c96c..6658e15f1 100644
--- a/gio/tests/httpd.c
+++ b/gio/tests/httpd.c
@@ -6,7 +6,7 @@ static char *root = NULL;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
static void
diff --git a/gio/tests/live-g-file.c b/gio/tests/live-g-file.c
index 316e23c9e..9e2cc0c27 100644
--- a/gio/tests/live-g-file.c
+++ b/gio/tests/live-g-file.c
@@ -1371,7 +1371,7 @@ main (int argc, char *argv[])
{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},
{"posix", 'x', 0, G_OPTION_ARG_NONE, &posix_compat,
"Test POSIX-specific features (unix permissions, symlinks)", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
test_suite = FALSE;
diff --git a/gio/tests/memory-output-stream.c b/gio/tests/memory-output-stream.c
index 72da6263d..b448516df 100644
--- a/gio/tests/memory-output-stream.c
+++ b/gio/tests/memory-output-stream.c
@@ -33,7 +33,7 @@ test_truncate (void)
GError *error = NULL;
guint8 *data;
- g_test_bug ("540423");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540423");
mo = g_memory_output_stream_new_resizable ();
g_assert (g_seekable_can_truncate (G_SEEKABLE (mo)));
@@ -66,7 +66,7 @@ test_truncate (void)
for (i = 1000; i < 3000; i++)
g_assert_cmpuint (data[i], ==, 2);
- g_test_bug ("720080");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=720080");
g_seekable_truncate (G_SEEKABLE (mo), 8192, NULL, &error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 8192);
@@ -199,7 +199,7 @@ test_data_size (void)
GDataOutputStream *o;
int pos;
- g_test_bug ("540459");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540459");
mo = g_memory_output_stream_new_resizable ();
o = g_data_output_stream_new (mo);
@@ -211,7 +211,7 @@ test_data_size (void)
pos = g_seekable_tell (G_SEEKABLE (mo));
g_assert_cmpint (pos, ==, 1);
- g_test_bug ("540461");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540461");
g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_SET, NULL, NULL);
pos = g_seekable_tell (G_SEEKABLE (mo));
@@ -239,7 +239,7 @@ test_properties (void)
gpointer data_prop;
gpointer func;
- g_test_bug ("605733");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=605733");
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
@@ -430,7 +430,6 @@ main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/memory-output-stream/truncate", test_truncate);
g_test_add_func ("/memory-output-stream/seek/fixed", test_seek_fixed);
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index a926ae01a..98d1401d0 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -675,10 +675,8 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
]
# Create object file containing resource data for testing the --external-data
- # option. Currently only GNU ld and GNU objcopy support the right options.
- # Support for --add-symbol was added to LLVM objcopy in 2019
- # (https://reviews.llvm.org/D58234). FIXME: This test could be enabled for
- # LLVM once that support is in a stable release.
+ # option. Currently only GNU ld and objcopy, or (as of 2019) LLVM ld and
+ # objcopy, support the right options.
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
@@ -687,7 +685,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
ld = find_program('ld', required : false)
- if build_machine.system() == 'linux' and cc.get_id() == 'gcc' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
+ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
test_gresource_binary = custom_target('test5.gresource',
input : 'test5.gresource.xml',
output : 'test5.gresource',
diff --git a/gio/tests/mimeapps.c b/gio/tests/mimeapps.c
index 08bcce247..6d7785299 100644
--- a/gio/tests/mimeapps.c
+++ b/gio/tests/mimeapps.c
@@ -5,7 +5,7 @@
static gboolean
strv_equal (gchar **strv, ...)
{
- gint count;
+ gsize count;
va_list list;
const gchar *str;
gboolean res;
diff --git a/gio/tests/network-address.c b/gio/tests/network-address.c
index cbebb6c9f..946a8f25f 100644
--- a/gio/tests/network-address.c
+++ b/gio/tests/network-address.c
@@ -1011,7 +1011,7 @@ test_happy_eyeballs_ipv6_error_ipv4_very_slow (HappyEyeballsFixture *fixture,
AsyncData data = { 0 };
GError *ipv6_error;
- g_test_bug ("merge_requests/865");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/865");
g_test_summary ("Ensure that we successfully return IPv4 results even when they come significantly later than an IPv6 failure.");
/* If ipv6 fails, ensuring that ipv6 errors before ipv4 finishes, we still get ipv4. */
@@ -1183,38 +1183,37 @@ test_happy_eyeballs_both_error_delays_3 (HappyEyeballsFixture *fixture,
int
main (int argc, char *argv[])
{
- gint i;
+ gsize i;
gchar *path;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/");
g_test_add_func ("/network-address/basic", test_basic);
for (i = 0; i < G_N_ELEMENTS (host_tests); i++)
{
- path = g_strdup_printf ("/network-address/parse-host/%d", i);
+ path = g_strdup_printf ("/network-address/parse-host/%" G_GSIZE_FORMAT, i);
g_test_add_data_func (path, &host_tests[i], test_parse_host);
g_free (path);
}
for (i = 0; i < G_N_ELEMENTS (uri_tests); i++)
{
- path = g_strdup_printf ("/network-address/parse-uri/%d", i);
+ path = g_strdup_printf ("/network-address/parse-uri/%" G_GSIZE_FORMAT, i);
g_test_add_data_func (path, &uri_tests[i], test_parse_uri);
g_free (path);
}
for (i = 0; i < G_N_ELEMENTS (address_tests); i++)
{
- path = g_strdup_printf ("/network-address/resolve-address/%d", i);
+ path = g_strdup_printf ("/network-address/resolve-address/%" G_GSIZE_FORMAT, i);
g_test_add_data_func (path, &address_tests[i], test_resolve_address);
g_free (path);
}
for (i = 0; i < G_N_ELEMENTS (address_tests); i++)
{
- path = g_strdup_printf ("/gresolver/resolve-address/%d", i);
+ path = g_strdup_printf ("/gresolver/resolve-address/%" G_GSIZE_FORMAT, i);
g_test_add_data_func (path, &address_tests[i], test_resolve_address_gresolver);
g_free (path);
}
diff --git a/gio/tests/network-monitor-race.c b/gio/tests/network-monitor-race.c
index 9c6866e6a..00bd6fa8e 100644
--- a/gio/tests/network-monitor-race.c
+++ b/gio/tests/network-monitor-race.c
@@ -58,7 +58,7 @@ test_network_monitor (void)
{
guint ii;
- g_test_bug ("793727");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=793727");
if (g_test_subprocess ())
{
@@ -86,7 +86,6 @@ int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
g_test_add_func ("/network-monitor/create-in-thread",
test_network_monitor);
diff --git a/gio/tests/org.gtk.schemasourcecheck.gschema.xml b/gio/tests/org.gtk.schemasourcecheck.gschema.xml
index 42c9c5104..b484da1a3 100644
--- a/gio/tests/org.gtk.schemasourcecheck.gschema.xml
+++ b/gio/tests/org.gtk.schemasourcecheck.gschema.xml
@@ -1,7 +1,8 @@
<schemalist>
- <schema id="org.gtk.schemasourcecheck" path="/tests/">
+ <schema id="org.gtk.schemasourcecheck">
<key name="enabled" type="b">
<default>true</default>
</key>
+ <child name="child" schema="org.gtk.schemasourcecheck" />
</schema>
</schemalist>
diff --git a/gio/tests/proxy-test.c b/gio/tests/proxy-test.c
index e3c0d09c7..eec4bf7ca 100644
--- a/gio/tests/proxy-test.c
+++ b/gio/tests/proxy-test.c
@@ -842,8 +842,8 @@ do_echo_test (GSocketConnection *conn)
GIOStream *iostream = G_IO_STREAM (conn);
GInputStream *istream = g_io_stream_get_input_stream (iostream);
GOutputStream *ostream = g_io_stream_get_output_stream (iostream);
- gssize nread, total;
- gsize nwrote;
+ gssize nread;
+ gsize nwrote, total;
gchar buf[128];
GError *error = NULL;
diff --git a/gio/tests/readwrite.c b/gio/tests/readwrite.c
index 2aa925b30..7551e5384 100644
--- a/gio/tests/readwrite.c
+++ b/gio/tests/readwrite.c
@@ -32,6 +32,7 @@ static void
verify_iostream (GFileIOStream *file_iostream)
{
gboolean res;
+ gssize skipped;
GIOStream *iostream;
GError *error;
GInputStream *in;
@@ -73,8 +74,9 @@ verify_iostream (GFileIOStream *file_iostream)
g_assert (res == 5);
verify_pos (iostream, 15);
- res = g_input_stream_skip (in, 10000, NULL, NULL);
- g_assert (res == strlen (original_data) - 15);
+ skipped = g_input_stream_skip (in, 10000, NULL, NULL);
+ g_assert_cmpint (skipped, >=, 0);
+ g_assert ((gsize) skipped == strlen (original_data) - 15);
verify_pos (iostream, strlen (original_data));
res = g_seekable_seek (G_SEEKABLE (iostream),
diff --git a/gio/tests/resolver.c b/gio/tests/resolver.c
index 3e6d89670..6e0c4d73b 100644
--- a/gio/tests/resolver.c
+++ b/gio/tests/resolver.c
@@ -672,7 +672,7 @@ static const GOptionEntry option_entries[] = {
{ "synchronous", 's', 0, G_OPTION_ARG_NONE, &synchronous, "Synchronous connections", NULL },
{ "connectable", 'c', 0, G_OPTION_ARG_INT, &connectable_count, "Connectable count", "C" },
{ "special-type", 't', 0, G_OPTION_ARG_CALLBACK, record_type_arg, "Record type like MX, TXT, NS or SOA", "RR" },
- { NULL },
+ G_OPTION_ENTRY_NULL,
};
int
diff --git a/gio/tests/send-data.c b/gio/tests/send-data.c
index a66976fa3..d70502eca 100644
--- a/gio/tests/send-data.c
+++ b/gio/tests/send-data.c
@@ -20,7 +20,7 @@ static GOptionEntry cmd_entries[] = {
"Time out socket I/O after the specified number of seconds", NULL},
{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
"Verbose debugging output", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
static gpointer
diff --git a/gio/tests/sleepy-stream.c b/gio/tests/sleepy-stream.c
index 664fb3b02..bbbeb2534 100644
--- a/gio/tests/sleepy-stream.c
+++ b/gio/tests/sleepy-stream.c
@@ -285,7 +285,6 @@ int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/filter-stream/input", test);
g_test_add_func ("/filter-stream/async", asynch);
diff --git a/gio/tests/socket-client.c b/gio/tests/socket-client.c
index 8df1c28f3..6c25e08c9 100644
--- a/gio/tests/socket-client.c
+++ b/gio/tests/socket-client.c
@@ -34,7 +34,7 @@ static GOptionEntry cmd_entries[] = {
"Time out reads after the specified number of seconds", NULL},
{"tls", 'T', 0, G_OPTION_ARG_NONE, &tls,
"Use TLS (SSL)", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
#include "socket-common.c"
diff --git a/gio/tests/socket-common.c b/gio/tests/socket-common.c
index e59fa9cd4..18d083a30 100644
--- a/gio/tests/socket-common.c
+++ b/gio/tests/socket-common.c
@@ -45,7 +45,7 @@ static GSocketAddress *
socket_address_from_string (const char *name)
{
#ifdef G_OS_UNIX
- int i, len;
+ gsize i, len;
for (i = 0; i < G_N_ELEMENTS (unix_socket_address_types); i++)
{
diff --git a/gio/tests/socket-listener.c b/gio/tests/socket-listener.c
index 71e70b28f..6ceed13d4 100644
--- a/gio/tests/socket-listener.c
+++ b/gio/tests/socket-listener.c
@@ -86,8 +86,6 @@ main (int argc,
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/socket-listener/event-signal", test_event_signal);
return g_test_run();
diff --git a/gio/tests/socket-server.c b/gio/tests/socket-server.c
index 24cf0182e..8b0d2a925 100644
--- a/gio/tests/socket-server.c
+++ b/gio/tests/socket-server.c
@@ -40,7 +40,7 @@ static GOptionEntry cmd_entries[] = {
"Time out reads after the specified number of seconds", NULL},
{"tls", 'T', 0, G_OPTION_ARG_STRING, &tls_cert_file,
"Use TLS (SSL) with indicated server certificate", "CERTFILE"},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
#include "socket-common.c"
diff --git a/gio/tests/socket-service.c b/gio/tests/socket-service.c
index c763fa6e6..a00c0c499 100644
--- a/gio/tests/socket-service.c
+++ b/gio/tests/socket-service.c
@@ -182,7 +182,7 @@ test_threaded_712570 (void)
GSocketClient *client;
GError *error = NULL;
- g_test_bug ("712570");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=712570");
g_mutex_lock (&mutex_712570);
@@ -557,8 +557,6 @@ main (int argc,
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/socket-service/start-stop", test_start_stop);
g_test_add_func ("/socket-service/threaded/712570", test_threaded_712570);
g_test_add_func ("/socket-service/read_write_async", test_read_write_async);
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index ee098c55f..fa96a4087 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -502,7 +502,7 @@ test_ip_sync (GSocketFamily family)
g_assert_cmpstr (testbuf, ==, buf);
{
- GOutputVector v[7] = { { NULL, }, };
+ GOutputVector v[7] = { { NULL, 0 }, };
v[0].buffer = testbuf2 + 0;
v[0].size = 3;
@@ -627,10 +627,10 @@ test_ip_sync_dgram (GSocketFamily family)
g_assert_cmpstr (testbuf, ==, buf);
{
- GOutputMessage m[3] = { { NULL, }, };
- GInputMessage im[3] = { { NULL, }, };
- GOutputVector v[7] = { { NULL, }, };
- GInputVector iv[7] = { { NULL, }, };
+ GOutputMessage m[3] = { { NULL, NULL, 0, 0, NULL, 0 }, };
+ GInputMessage im[3] = { { NULL, NULL, 0, 0, 0, NULL, 0 }, };
+ GOutputVector v[7] = { { NULL, 0 }, };
+ GInputVector iv[7] = { { NULL, 0 }, };
v[0].buffer = testbuf2 + 0;
v[0].size = 3;
@@ -868,8 +868,8 @@ test_ip_sync_dgram_timeouts (GSocketFamily family)
/* Check for timeouts when no server is running. */
{
gint64 start_time;
- GInputMessage im = { NULL, };
- GInputVector iv = { NULL, };
+ GInputMessage im = { NULL, NULL, 0, 0, 0, NULL, 0 };
+ GInputVector iv = { NULL, 0 };
guint8 buf[128];
iv.buffer = buf;
@@ -1227,7 +1227,7 @@ test_fd_reuse (void)
gssize len;
gchar buf[128];
- g_test_bug ("741707");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=741707");
data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error);
if (error != NULL)
@@ -1694,7 +1694,8 @@ test_get_available (gconstpointer user_data)
for (tries = 0; tries < 100; tries++)
{
- if (g_socket_get_available_bytes (server) > sizeof (data))
+ gssize res = g_socket_get_available_bytes (server);
+ if ((res == -1) || ((gsize) res > sizeof (data)))
break;
g_usleep (100000);
}
@@ -2139,7 +2140,6 @@ main (int argc,
GError *error = NULL;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/");
sock = g_socket_new (G_SOCKET_FAMILY_IPV6,
G_SOCKET_TYPE_STREAM,
diff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c
index b74dc2b71..a52ade715 100644
--- a/gio/tests/testfilemonitor.c
+++ b/gio/tests/testfilemonitor.c
@@ -118,7 +118,8 @@ check_expected_events (RecordedEvent *expected,
GList *recorded,
Environment env)
{
- gint i, li;
+ gsize i;
+ gint li;
GList *l;
for (i = 0, li = 0, l = recorded; i < n_expected && l != NULL;)
@@ -217,7 +218,7 @@ check_expected_events (RecordedEvent *expected,
e2->event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
{
g_test_message ("Event CHANGES_DONE_HINT ignored at "
- "expected index %d, recorded index %d", i, li);
+ "expected index %" G_GSIZE_FORMAT ", recorded index %d", i, li);
li++, l = l->next;
continue;
}
@@ -225,7 +226,7 @@ check_expected_events (RecordedEvent *expected,
* the event doesn't match, it means the expected event has lost. */
else if (env & e1->optional)
{
- g_test_message ("Event %d at expected index %d skipped because "
+ g_test_message ("Event %d at expected index %" G_GSIZE_FORMAT " skipped because "
"it is marked as optional", e1->event_type, i);
i++;
continue;
@@ -957,7 +958,7 @@ test_file_hard_links (Fixture *fixture,
GError *error = NULL;
TestData data;
- g_test_bug ("755721");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=755721");
#ifdef HAVE_LINK
g_test_message ("Running with hard link tests");
@@ -1011,8 +1012,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
-
g_test_add ("/monitor/atomic-replace", Fixture, NULL, setup, test_atomic_replace, teardown);
g_test_add ("/monitor/file-changes", Fixture, NULL, setup, test_file_changes, teardown);
g_test_add ("/monitor/dir-monitor", Fixture, NULL, setup, test_dir_monitor, teardown);
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index 9dd415091..2995b1028 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -40,7 +40,7 @@ pem_parser (const Reference *ref)
gchar *pem;
gsize pem_len = 0;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
/* Check PEM parsing in certificate, private key order. */
@@ -55,13 +55,12 @@ pem_parser (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_object_unref (cert);
@@ -89,13 +88,12 @@ pem_parser (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_free (pem);
g_object_unref (cert);
@@ -111,11 +109,10 @@ pem_parser (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_null (parsed_key_pem);
g_free (pem);
@@ -141,7 +138,7 @@ pem_parser_handles_chain (const Reference *ref)
GTlsCertificate *original_cert;
gchar *pem;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
/* Check that a chain with exactly three certificates is returned */
@@ -156,14 +153,14 @@ pem_parser_handles_chain (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
g_clear_pointer (&parsed_cert_pem, g_free);
/* Make sure the private key was parsed */
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
/* Now test the second cert */
issuer = g_tls_certificate_get_issuer (cert);
@@ -175,12 +172,12 @@ pem_parser_handles_chain (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[1]);
g_clear_pointer (&parsed_cert_pem, g_free);
/* Only the first cert should have a private key */
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_null (parsed_key_pem);
/* Now test the final cert */
@@ -190,11 +187,11 @@ pem_parser_handles_chain (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[2]);
g_clear_pointer (&parsed_cert_pem, g_free);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_null (parsed_key_pem);
g_object_unref (original_cert);
@@ -237,7 +234,7 @@ from_file (const Reference *ref)
{
GTlsCertificate *cert;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
cert = g_tls_certificate_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
@@ -247,13 +244,12 @@ from_file (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_object_unref (cert);
}
@@ -263,7 +259,7 @@ from_files (const Reference *ref)
{
GTlsCertificate *cert;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
@@ -274,13 +270,12 @@ from_files (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_object_unref (cert);
@@ -332,7 +327,7 @@ from_files_crlf (const Reference *ref)
{
GTlsCertificate *cert;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-crlf.pem", NULL),
@@ -343,13 +338,12 @@ from_files_crlf (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_crlf_pem);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key_crlf_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_object_unref (cert);
}
@@ -359,7 +353,7 @@ from_files_pkcs8 (const Reference *ref)
{
GTlsCertificate *cert;
gchar *parsed_cert_pem = NULL;
- const gchar *parsed_key_pem = NULL;
+ gchar *parsed_key_pem = NULL;
GError *error = NULL;
cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
@@ -370,13 +364,12 @@ from_files_pkcs8 (const Reference *ref)
g_object_get (cert,
"certificate-pem", &parsed_cert_pem,
+ "private-key-pem", &parsed_key_pem,
NULL);
- parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
- g_free (parsed_cert_pem);
- parsed_cert_pem = NULL;
+ g_clear_pointer (&parsed_cert_pem, g_free);
g_assert_cmpstr (parsed_key_pem, ==, ref->key8_pem);
- parsed_key_pem = NULL;
+ g_clear_pointer (&parsed_key_pem, g_free);
g_object_unref (cert);
}
@@ -462,6 +455,137 @@ from_unsupported_pkcs11_uri (void)
g_clear_error (&error);
}
+static void
+not_valid_before (void)
+{
+ const gchar *EXPECTED_NOT_VALID_BEFORE = "2020-10-12T17:49:44Z";
+
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ GDateTime *actual;
+ gchar *actual_str;
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_not_valid_before (cert);
+ g_assert_nonnull (actual);
+ actual_str = g_date_time_format_iso8601 (actual);
+ g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_BEFORE);
+ g_free (actual_str);
+ g_date_time_unref (actual);
+ g_object_unref (cert);
+}
+
+static void
+not_valid_after (void)
+{
+ const gchar *EXPECTED_NOT_VALID_AFTER = "2045-10-06T17:49:44Z";
+
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ GDateTime *actual;
+ gchar *actual_str;
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_not_valid_after (cert);
+ g_assert_nonnull (actual);
+ actual_str = g_date_time_format_iso8601 (actual);
+ g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_AFTER);
+ g_free (actual_str);
+ g_date_time_unref (actual);
+ g_object_unref (cert);
+}
+
+static void
+subject_name (void)
+{
+ const gchar *EXPECTED_SUBJECT_NAME = "DC=COM,DC=EXAMPLE,CN=server.example.com";
+
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ gchar *actual;
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_subject_name (cert);
+ g_assert_nonnull (actual);
+ g_assert_cmpstr (actual, ==, EXPECTED_SUBJECT_NAME);
+ g_free (actual);
+ g_object_unref (cert);
+}
+
+static void
+issuer_name (void)
+{
+ const gchar *EXPECTED_ISSUER_NAME = "DC=COM,DC=EXAMPLE,OU=Certificate Authority,CN=ca.example.com,emailAddress=ca@example.com";
+
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ gchar *actual;
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_issuer_name (cert);
+ g_assert_nonnull (actual);
+ g_assert_cmpstr (actual, ==, EXPECTED_ISSUER_NAME);
+ g_free (actual);
+ g_object_unref (cert);
+}
+
+static void
+dns_names (void)
+{
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ GPtrArray *actual;
+ const gchar *dns_name = "a.example.com";
+ GBytes *expected = g_bytes_new_static (dns_name, strlen (dns_name));
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_dns_names (cert);
+ g_assert_nonnull (actual);
+ g_assert_cmpuint (actual->len, ==, 1);
+ g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_bytes_equal, NULL));
+
+ g_ptr_array_free (actual, FALSE);
+ g_bytes_unref (expected);
+ g_object_unref (cert);
+}
+
+static void
+ip_addresses (void)
+{
+ GTlsCertificate *cert;
+ GError *error = NULL;
+ GPtrArray *actual;
+ GInetAddress *expected = g_inet_address_new_from_string ("192.0.2.1");
+
+ cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (cert);
+
+ actual = g_tls_certificate_get_ip_addresses (cert);
+ g_assert_nonnull (actual);
+ g_assert_cmpuint (actual->len, ==, 1);
+ g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_inet_address_equal, NULL));
+
+ g_ptr_array_free (actual, TRUE);
+ g_object_unref (expected);
+ g_object_unref (cert);
+}
+
int
main (int argc,
char *argv[])
@@ -532,6 +656,18 @@ main (int argc,
from_pkcs11_uri);
g_test_add_func ("/tls-certificate/pkcs11-uri-unsupported",
from_unsupported_pkcs11_uri);
+ g_test_add_func ("/tls-certificate/not-valid-before",
+ not_valid_before);
+ g_test_add_func ("/tls-certificate/not-valid-after",
+ not_valid_after);
+ g_test_add_func ("/tls-certificate/subject-name",
+ subject_name);
+ g_test_add_func ("/tls-certificate/issuer-name",
+ issuer_name);
+ g_test_add_func ("/tls-certificate/dns-names",
+ dns_names);
+ g_test_add_func ("/tls-certificate/ip-addresses",
+ ip_addresses);
g_test_add_func ("/tls-certificate/pem-parser-no-sentinel",
pem_parser_no_sentinel);
diff --git a/gio/tests/trash.c b/gio/tests/trash.c
index adf729be2..2d3ec6774 100644
--- a/gio/tests/trash.c
+++ b/gio/tests/trash.c
@@ -38,7 +38,7 @@ test_trash_not_supported (void)
gchar *parent_dirname;
GStatBuf parent_stat, home_stat;
- g_test_bug ("251");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/251");
/* The test assumes that tmp file is located on system internal mount. */
file = g_file_new_tmp ("test-trashXXXXXX", &stream, &error);
@@ -105,7 +105,7 @@ test_trash_symlinks (void)
gchar *target, *tmp, *target_over_symlink;
GError *error = NULL;
- g_test_bug ("1522");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1522");
target = g_build_filename (g_get_home_dir (), ".local", NULL);
@@ -204,8 +204,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/issues/");
-
g_test_add_func ("/trash/not-supported", test_trash_not_supported);
g_test_add_func ("/trash/symlinks", test_trash_symlinks);
diff --git a/gio/tests/unix-streams.c b/gio/tests/unix-streams.c
index 5ec829919..407a67dbd 100644
--- a/gio/tests/unix-streams.c
+++ b/gio/tests/unix-streams.c
@@ -474,8 +474,9 @@ test_write_wouldblock (void)
gint fd[2];
GError *err = NULL;
guint8 data_write[1024], data_read[1024];
- guint i;
- gint pipe_capacity;
+ gsize i;
+ int retval;
+ gsize pipe_capacity;
for (i = 0; i < sizeof (data_write); i++)
data_write[i] = i;
@@ -483,7 +484,9 @@ test_write_wouldblock (void)
g_assert_cmpint (pipe (fd), ==, 0);
g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0);
- pipe_capacity = fcntl (fd[0], F_GETPIPE_SZ, &pipe_capacity, NULL);
+ retval = fcntl (fd[0], F_GETPIPE_SZ);
+ g_assert_cmpint (retval, >=, 0);
+ pipe_capacity = (gsize) retval;
g_assert_cmpint (pipe_capacity, >=, 4096);
g_assert_cmpint (pipe_capacity % 1024, >=, 0);
@@ -552,10 +555,11 @@ test_writev_wouldblock (void)
gint fd[2];
GError *err = NULL;
guint8 data_write[1024], data_read[1024];
- guint i;
+ gsize i;
+ int retval;
+ gsize pipe_capacity;
GOutputVector vectors[4];
GPollableReturn res;
- gint pipe_capacity;
for (i = 0; i < sizeof (data_write); i++)
data_write[i] = i;
@@ -563,7 +567,9 @@ test_writev_wouldblock (void)
g_assert_cmpint (pipe (fd), ==, 0);
g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0);
- pipe_capacity = fcntl (fd[0], F_GETPIPE_SZ, &pipe_capacity, NULL);
+ retval = fcntl (fd[0], F_GETPIPE_SZ);
+ g_assert_cmpint (retval, >=, 0);
+ pipe_capacity = (gsize) retval;
g_assert_cmpint (pipe_capacity, >=, 4096);
g_assert_cmpint (pipe_capacity % 1024, >=, 0);
@@ -667,8 +673,9 @@ test_write_async_wouldblock (void)
GUnixOutputStream *os;
gint fd[2];
guint8 *data, *data_read;
- guint i;
- gint pipe_capacity;
+ gsize i;
+ int retval;
+ gsize pipe_capacity;
gsize bytes_written = 0, bytes_read = 0;
g_assert_cmpint (pipe (fd), ==, 0);
@@ -685,7 +692,9 @@ test_write_async_wouldblock (void)
g_unix_set_fd_nonblocking (fd[1], TRUE, NULL);
g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0);
- pipe_capacity = fcntl (fd[0], F_GETPIPE_SZ, &pipe_capacity, NULL);
+ retval = fcntl (fd[0], F_GETPIPE_SZ);
+ g_assert_cmpint (retval, >=, 0);
+ pipe_capacity = (gsize) retval;
g_assert_cmpint (pipe_capacity, >=, 4096);
data = g_new (guint8, 4 * pipe_capacity);
@@ -754,8 +763,9 @@ test_writev_async_wouldblock (void)
GUnixOutputStream *os;
gint fd[2];
guint8 *data, *data_read;
- guint i;
- gint pipe_capacity;
+ gsize i;
+ int retval;
+ gsize pipe_capacity;
gsize bytes_written = 0, bytes_read = 0;
GOutputVector vectors[4];
@@ -773,7 +783,9 @@ test_writev_async_wouldblock (void)
g_unix_set_fd_nonblocking (fd[1], TRUE, NULL);
g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0);
- pipe_capacity = fcntl (fd[0], F_GETPIPE_SZ, &pipe_capacity, NULL);
+ retval = fcntl (fd[0], F_GETPIPE_SZ);
+ g_assert_cmpint (retval, >=, 0);
+ pipe_capacity = (gsize) retval;
g_assert_cmpint (pipe_capacity, >=, 4096);
data = g_new (guint8, 4 * pipe_capacity);
diff --git a/glib.doap b/glib.doap
index a300f51cb..2d199101e 100644
--- a/glib.doap
+++ b/glib.doap
@@ -56,7 +56,7 @@
<repository>
<GitRepository>
- <browse rdf:resource="https://gitlab.gnome.org/GNOME/glib/tree/master"/>
+ <browse rdf:resource="https://gitlab.gnome.org/GNOME/glib/"/>
<location rdf:resource="https://gitlab.gnome.org/GNOME/glib.git"/>
</GitRepository>
</repository>
diff --git a/glib.supp b/glib.supp
index 283166361..748216850 100644
--- a/glib.supp
+++ b/glib.supp
@@ -700,7 +700,7 @@
fun:g_inet_address_get_type
}
-# From: https://github.com/fredericgermain/valgrind/blob/master/glibc-2.X-drd.supp
+# From: https://github.com/fredericgermain/valgrind/blob/HEAD/glibc-2.X-drd.supp
{
drd-libc-stdio
drd:ConflictingAccess
diff --git a/glib/deprecated/gthread.h b/glib/deprecated/gthread.h
index 33b422240..2d490a110 100644
--- a/glib/deprecated/gthread.h
+++ b/glib/deprecated/gthread.h
@@ -125,7 +125,11 @@ void g_thread_foreach (GFunc thread_func,
#endif
#define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl GLIB_DEPRECATED_MACRO_IN_2_32
+#ifndef G_OS_WIN32
+#define G_STATIC_MUTEX_INIT { NULL, PTHREAD_MUTEX_INITIALIZER } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_init)
+#else
#define G_STATIC_MUTEX_INIT { NULL } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_init)
+#endif
typedef struct
{
GMutex *mutex;
diff --git a/glib/dirent/dirent.c b/glib/dirent/dirent.c
index 26b6cb1e5..5b8f3ff80 100644
--- a/glib/dirent/dirent.c
+++ b/glib/dirent/dirent.c
@@ -135,7 +135,7 @@ _topendir (const _TCHAR *szPath)
nd->dd_dir.d_ino = 0;
nd->dd_dir.d_reclen = 0;
nd->dd_dir.d_namlen = 0;
- memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
+ memset (nd->dd_dir.d_name, 0, sizeof (nd->dd_dir.d_name));
return nd;
}
diff --git a/glib/dirent/dirent.h b/glib/dirent/dirent.h
index 237665b4e..857710f6a 100644
--- a/glib/dirent/dirent.h
+++ b/glib/dirent/dirent.h
@@ -22,7 +22,7 @@ struct dirent
long d_ino; /* Always zero. */
unsigned short d_reclen; /* Always zero. */
unsigned short d_namlen; /* Length of name in d_name. */
- char d_name[FILENAME_MAX]; /* File name. */
+ char d_name[FILENAME_MAX+1]; /* File name plus nul delimiter. */
};
#ifdef _WIN64
@@ -76,7 +76,7 @@ struct _wdirent
long d_ino; /* Always zero. */
unsigned short d_reclen; /* Always zero. */
unsigned short d_namlen; /* Length of name in d_name. */
- wchar_t d_name[FILENAME_MAX]; /* File name. */
+ wchar_t d_name[FILENAME_MAX+1]; /* File name plus nul delimiter. */
};
/*
diff --git a/glib/galloca.h b/glib/galloca.h
index 47151ee8b..014a0efcb 100644
--- a/glib/galloca.h
+++ b/glib/galloca.h
@@ -81,6 +81,11 @@ G_END_DECLS
* way as out of stack space situations from infinite function recursion, i.e.
* with a segmentation fault.
*
+ * - Allowing @size to be specified by an untrusted party would allow for them
+ * to trigger a segmentation fault by specifying a large size, leading to a
+ * denial of service vulnerability. @size must always be entirely under the
+ * control of the program.
+ *
* - Special care has to be taken when mixing alloca() with GNU C variable sized arrays.
* Stack space allocated with alloca() in the same scope as a variable sized array
* will be freed together with the variable sized array upon exit of that scope, and
@@ -96,6 +101,12 @@ G_END_DECLS
*
* Wraps g_alloca() in a more typesafe manner.
*
+ * As mentioned in the documentation for g_alloca(), @n_structs must always be
+ * entirely under the control of the program, or you may introduce a denial of
+ * service vulnerability. In addition, the multiplication of @struct_type by
+ * @n_structs is not checked, so an overflow may lead to a remote code execution
+ * vulnerability.
+ *
* Returns: Pointer to stack space for @n_structs chunks of type @struct_type
*/
#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs)))
diff --git a/glib/garray.c b/glib/garray.c
index 2b66f16a6..025747ee5 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -188,7 +188,7 @@ g_array_new (gboolean zero_terminated,
/**
* g_array_steal:
* @array: a #GArray.
- * @len: (optional) (out caller-allocates): pointer to retrieve the number of
+ * @len: (optional) (out): pointer to retrieve the number of
* elements of the original array
*
* Frees the data in the array and resets the size to zero, while
@@ -299,6 +299,27 @@ g_array_sized_new (gboolean zero_terminated,
* functions, @clear_func is expected to clear the contents of
* the array element it is given, but not free the element itself.
*
+ * |[<!-- language="C" -->
+ * typedef struct
+ * {
+ * gchar *str;
+ * GObject *obj;
+ * } ArrayElement;
+ *
+ * static void
+ * array_element_clear (ArrayElement *element)
+ * {
+ * g_clear_pointer (&element->str, g_free);
+ * g_clear_object (&element->obj);
+ * }
+ *
+ * // main code
+ * GArray *garray = g_array_new (FALSE, FALSE, sizeof (ArrayElement));
+ * g_array_set_clear_func (garray, (GDestroyNotify) array_element_clear);
+ * // assign data to the structure
+ * g_array_free (garray, TRUE);
+ * ]|
+ *
* Since: 2.32
*/
void
@@ -867,7 +888,7 @@ g_array_sort_with_data (GArray *farray,
* @array: a #GArray.
* @target: a pointer to the item to look up.
* @compare_func: A #GCompareFunc used to locate @target.
- * @out_match_index: (optional) (out caller-allocates): return location
+ * @out_match_index: (optional) (out): return location
* for the index of the element, if found.
*
* Checks whether @target exists in @array by performing a binary
@@ -1114,7 +1135,7 @@ g_ptr_array_new (void)
/**
* g_ptr_array_steal:
* @array: a #GPtrArray.
- * @len: (optional) (out caller-allocates): pointer to retrieve the number of
+ * @len: (optional) (out): pointer to retrieve the number of
* elements of the original array
*
* Frees the data in the array and resets the size to zero, while
@@ -2099,7 +2120,7 @@ g_ptr_array_foreach (GPtrArray *array,
* g_ptr_array_find: (skip)
* @haystack: pointer array to be searched
* @needle: pointer to look for
- * @index_: (optional) (out caller-allocates): return location for the index of
+ * @index_: (optional) (out): return location for the index of
* the element, if found
*
* Checks whether @needle exists in @haystack. If the element is found, %TRUE is
@@ -2128,7 +2149,7 @@ g_ptr_array_find (GPtrArray *haystack,
* @equal_func: (nullable): the function to call for each element, which should
* return %TRUE when the desired element is found; or %NULL to use pointer
* equality
- * @index_: (optional) (out caller-allocates): return location for the index of
+ * @index_: (optional) (out): return location for the index of
* the element, if found
*
* Checks whether @needle exists in @haystack, using the given @equal_func.
@@ -2234,7 +2255,7 @@ g_byte_array_new (void)
/**
* g_byte_array_steal:
* @array: a #GByteArray.
- * @len: (optional) (out caller-allocates): pointer to retrieve the number of
+ * @len: (optional) (out): pointer to retrieve the number of
* elements of the original array
*
* Frees the data in the array and resets the size to zero, while
diff --git a/glib/gasyncqueue.c b/glib/gasyncqueue.c
index a452617fd..db053f399 100644
--- a/glib/gasyncqueue.c
+++ b/glib/gasyncqueue.c
@@ -123,7 +123,7 @@ g_async_queue_new (void)
/**
* g_async_queue_new_full:
- * @item_free_func: function to free queue elements
+ * @item_free_func: (nullable): function to free queue elements
*
* Creates a new asynchronous queue and sets up a destroy notify
* function that is used to free any remaining queue items when
diff --git a/glib/gatomic.h b/glib/gatomic.h
index 2ad648aad..5583fb0c9 100644
--- a/glib/gatomic.h
+++ b/glib/gatomic.h
@@ -25,11 +25,7 @@
#endif
#include <glib/gtypes.h>
-
-#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
-/* for glib_typeof */
-#include <type_traits>
-#endif
+#include <glib/glib-typeof.h>
G_BEGIN_DECLS
@@ -108,7 +104,7 @@ G_END_DECLS
__atomic_store ((gint *)(atomic), &gais_temp, __ATOMIC_SEQ_CST); \
}))
-#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof)
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
@@ -125,7 +121,7 @@ G_END_DECLS
(void) (0 ? (gpointer) * (atomic) : NULL); \
__atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
}))
-#else /* if !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
+#else /* if !(defined(glib_typeof) */
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
@@ -142,7 +138,7 @@ G_END_DECLS
(void) (0 ? (gpointer) *(atomic) : NULL); \
__atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
}))
-#endif /* if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68) */
+#endif /* if defined(glib_typeof) */
#define g_atomic_int_inc(atomic) \
(G_GNUC_EXTENSION ({ \
@@ -307,7 +303,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
gapg_result; \
}))
-#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof)
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
@@ -316,7 +312,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
*(atomic) = (glib_typeof (*(atomic))) (gsize) (newval); \
}))
-#else /* if !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
+#else /* if !(defined(glib_typeof) */
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
@@ -325,7 +321,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
*(atomic) = (gpointer) (gsize) (newval); \
}))
-#endif /* if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68) */
+#endif /* if defined(glib_typeof) */
#define g_atomic_int_inc(atomic) \
(G_GNUC_EXTENSION ({ \
@@ -428,7 +424,7 @@ G_END_DECLS
#define g_atomic_int_dec_and_test(atomic) \
(g_atomic_int_dec_and_test ((gint *) (atomic)))
-#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof)
/* The (void *) cast in the middle *looks* redundant, because
* g_atomic_pointer_get returns void * already, but it's to silence
* -Werror=bad-function-cast when we're doing something like:
@@ -438,7 +434,7 @@ G_END_DECLS
* non-pointer-typed result. */
#define g_atomic_pointer_get(atomic) \
(glib_typeof (*(atomic))) (void *) ((g_atomic_pointer_get) ((void *) atomic))
-#else /* !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
+#else /* !(defined(glib_typeof) */
#define g_atomic_pointer_get(atomic) \
(g_atomic_pointer_get (atomic))
#endif
diff --git a/glib/gbitlock.c b/glib/gbitlock.c
index 45fb50999..9384d1a44 100644
--- a/glib/gbitlock.c
+++ b/glib/gbitlock.c
@@ -22,6 +22,7 @@
#include "gbitlock.h"
+#include <glib/gmacros.h>
#include <glib/gmessages.h>
#include <glib/gatomic.h>
#include <glib/gslist.h>
@@ -75,8 +76,8 @@ static GSList *g_futex_address_list = NULL;
* separate process.
*/
static void
-g_futex_wait (const volatile gint *address,
- gint value)
+g_futex_wait (const gint *address,
+ gint value)
{
syscall (__NR_futex, address, (gsize) FUTEX_WAIT_PRIVATE, (gsize) value, NULL);
}
@@ -93,7 +94,7 @@ g_futex_wait (const volatile gint *address,
* thread being woken up.
*/
static void
-g_futex_wake (const volatile gint *address)
+g_futex_wake (const gint *address)
{
syscall (__NR_futex, address, (gsize) FUTEX_WAKE_PRIVATE, (gsize) 1, NULL);
}
@@ -103,13 +104,13 @@ g_futex_wake (const volatile gint *address)
/* emulate futex(2) */
typedef struct
{
- const volatile gint *address;
- gint ref_count;
- GCond wait_queue;
+ const gint *address;
+ gint ref_count;
+ GCond wait_queue;
} WaitAddress;
static WaitAddress *
-g_futex_find_address (const volatile gint *address)
+g_futex_find_address (const gint *address)
{
GSList *node;
@@ -125,8 +126,8 @@ g_futex_find_address (const volatile gint *address)
}
static void
-g_futex_wait (const volatile gint *address,
- gint value)
+g_futex_wait (const gint *address,
+ gint value)
{
g_mutex_lock (&g_futex_mutex);
if G_LIKELY (g_atomic_int_get (address) == value)
@@ -158,7 +159,7 @@ g_futex_wait (const volatile gint *address,
}
static void
-g_futex_wake (const volatile gint *address)
+g_futex_wake (const gint *address)
{
WaitAddress *waiter;
@@ -176,10 +177,10 @@ g_futex_wake (const volatile gint *address)
#endif
#define CONTENTION_CLASSES 11
-static volatile gint g_bit_lock_contended[CONTENTION_CLASSES];
+static gint g_bit_lock_contended[CONTENTION_CLASSES]; /* (atomic) */
#if (defined (i386) || defined (__amd64__))
- #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+ #if G_GNUC_CHECK_VERSION(4, 5)
#define USE_ASM_GOTO 1
#endif
#endif
@@ -201,7 +202,8 @@ static volatile gint g_bit_lock_contended[CONTENTION_CLASSES];
*
* This function accesses @address atomically. All other accesses to
* @address must be atomic in order for this function to work
- * reliably.
+ * reliably. While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
*
* Since: 2.24
**/
@@ -209,6 +211,8 @@ void
g_bit_lock (volatile gint *address,
gint lock_bit)
{
+ gint *address_nonvolatile = (gint *) address;
+
#ifdef USE_ASM_GOTO
retry:
__asm__ volatile goto ("lock bts %1, (%0)\n"
@@ -224,13 +228,13 @@ g_bit_lock (volatile gint *address,
guint mask = 1u << lock_bit;
guint v;
- v = (guint) g_atomic_int_get (address);
+ v = (guint) g_atomic_int_get (address_nonvolatile);
if (v & mask)
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
g_atomic_int_add (&g_bit_lock_contended[class], +1);
- g_futex_wait (address, v);
+ g_futex_wait (address_nonvolatile, v);
g_atomic_int_add (&g_bit_lock_contended[class], -1);
}
}
@@ -240,14 +244,14 @@ g_bit_lock (volatile gint *address,
guint v;
retry:
- v = g_atomic_int_or (address, mask);
+ v = g_atomic_int_or (address_nonvolatile, mask);
if (v & mask)
/* already locked */
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
g_atomic_int_add (&g_bit_lock_contended[class], +1);
- g_futex_wait (address, v);
+ g_futex_wait (address_nonvolatile, v);
g_atomic_int_add (&g_bit_lock_contended[class], -1);
goto retry;
@@ -271,7 +275,8 @@ g_bit_lock (volatile gint *address,
*
* This function accesses @address atomically. All other accesses to
* @address must be atomic in order for this function to work
- * reliably.
+ * reliably. While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
*
* Returns: %TRUE if the lock was acquired
*
@@ -293,10 +298,11 @@ g_bit_trylock (volatile gint *address,
return result;
#else
+ gint *address_nonvolatile = (gint *) address;
guint mask = 1u << lock_bit;
guint v;
- v = g_atomic_int_or (address, mask);
+ v = g_atomic_int_or (address_nonvolatile, mask);
return ~v & mask;
#endif
@@ -313,7 +319,8 @@ g_bit_trylock (volatile gint *address,
*
* This function accesses @address atomically. All other accesses to
* @address must be atomic in order for this function to work
- * reliably.
+ * reliably. While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
*
* Since: 2.24
**/
@@ -321,6 +328,8 @@ void
g_bit_unlock (volatile gint *address,
gint lock_bit)
{
+ gint *address_nonvolatile = (gint *) address;
+
#ifdef USE_ASM_GOTO
__asm__ volatile ("lock btr %1, (%0)"
: /* no output */
@@ -329,14 +338,14 @@ g_bit_unlock (volatile gint *address,
#else
guint mask = 1u << lock_bit;
- g_atomic_int_and (address, ~mask);
+ g_atomic_int_and (address_nonvolatile, ~mask);
#endif
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
if (g_atomic_int_get (&g_bit_lock_contended[class]))
- g_futex_wake (address);
+ g_futex_wake (address_nonvolatile);
}
}
@@ -365,10 +374,10 @@ g_bit_unlock (volatile gint *address,
*
* g_futex_wake (g_futex_int_address (int_address));
*/
-static const volatile gint *
-g_futex_int_address (const volatile void *address)
+static const gint *
+g_futex_int_address (const void *address)
{
- const volatile gint *int_address = address;
+ const gint *int_address = address;
/* this implementation makes these (reasonable) assumptions: */
G_STATIC_ASSERT (G_BYTE_ORDER == G_LITTLE_ENDIAN ||
@@ -394,12 +403,17 @@ g_futex_int_address (const volatile void *address)
* For portability reasons, you may only lock on the bottom 32 bits of
* the pointer.
*
+ * While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
+ *
* Since: 2.30
**/
void
(g_pointer_bit_lock) (volatile void *address,
gint lock_bit)
{
+ void *address_nonvolatile = (void *) address;
+
g_return_if_fail (lock_bit < 32);
{
@@ -415,23 +429,23 @@ void
contended:
{
- volatile gsize *pointer_address = address;
+ gsize *pointer_address = address_nonvolatile;
gsize mask = 1u << lock_bit;
gsize v;
v = (gsize) g_atomic_pointer_get (pointer_address);
if (v & mask)
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
g_atomic_int_add (&g_bit_lock_contended[class], +1);
- g_futex_wait (g_futex_int_address (address), v);
+ g_futex_wait (g_futex_int_address (address_nonvolatile), v);
g_atomic_int_add (&g_bit_lock_contended[class], -1);
}
}
goto retry;
#else
- volatile gsize *pointer_address = address;
+ gsize *pointer_address = address_nonvolatile;
gsize mask = 1u << lock_bit;
gsize v;
@@ -440,10 +454,10 @@ void
if (v & mask)
/* already locked */
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
g_atomic_int_add (&g_bit_lock_contended[class], +1);
- g_futex_wait (g_futex_int_address (address), (guint) v);
+ g_futex_wait (g_futex_int_address (address_nonvolatile), (guint) v);
g_atomic_int_add (&g_bit_lock_contended[class], -1);
goto retry;
@@ -457,12 +471,15 @@ void
* @address: (not nullable): a pointer to a #gpointer-sized value
* @lock_bit: a bit value between 0 and 31
*
- * This is equivalent to g_bit_trylock, but working on pointers (or
+ * This is equivalent to g_bit_trylock(), but working on pointers (or
* other pointer-sized values).
*
* For portability reasons, you may only lock on the bottom 32 bits of
* the pointer.
*
+ * While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
+ *
* Returns: %TRUE if the lock was acquired
*
* Since: 2.30
@@ -486,7 +503,8 @@ gboolean
return result;
#else
- volatile gsize *pointer_address = address;
+ void *address_nonvolatile = (void *) address;
+ gsize *pointer_address = address_nonvolatile;
gsize mask = 1u << lock_bit;
gsize v;
@@ -510,12 +528,17 @@ gboolean
* For portability reasons, you may only lock on the bottom 32 bits of
* the pointer.
*
+ * While @address has a `volatile` qualifier, this is a historical
+ * artifact and the argument passed to it should not be `volatile`.
+ *
* Since: 2.30
**/
void
(g_pointer_bit_unlock) (volatile void *address,
gint lock_bit)
{
+ void *address_nonvolatile = (void *) address;
+
g_return_if_fail (lock_bit < 32);
{
@@ -525,16 +548,16 @@ void
: "r" (address), "r" ((gsize) lock_bit)
: "cc", "memory");
#else
- volatile gsize *pointer_address = address;
+ gsize *pointer_address = address_nonvolatile;
gsize mask = 1u << lock_bit;
g_atomic_pointer_and (pointer_address, ~mask);
#endif
{
- guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+ guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended);
if (g_atomic_int_get (&g_bit_lock_contended[class]))
- g_futex_wake (g_futex_int_address (address));
+ g_futex_wake (g_futex_int_address (address_nonvolatile));
}
}
}
diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c
index ff74a2e2d..14536ec9b 100644
--- a/glib/gbookmarkfile.c
+++ b/glib/gbookmarkfile.c
@@ -80,7 +80,7 @@
* displaying the bookmark inside a GUI.
*
* Here is an example of a bookmark file:
- * [bookmarks.xbel](https://git.gnome.org/browse/glib/tree/glib/tests/bookmarks.xbel)
+ * [bookmarks.xbel](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/glib/tests/bookmarks.xbel)
*
* A bookmark file might contain more than one bookmark; each bookmark
* is accessed through its URI.
@@ -552,9 +552,7 @@ static gchar *
bookmark_item_dump (BookmarkItem *item)
{
GString *retval;
- gchar *added, *visited, *modified;
gchar *escaped_uri;
- gchar *buffer;
/* at this point, we must have at least a registered application; if we don't
* we don't screw up the bookmark file, and just skip this item
@@ -567,43 +565,63 @@ bookmark_item_dump (BookmarkItem *item)
retval = g_string_sized_new (4096);
- added = g_date_time_format_iso8601 (item->added);
- modified = g_date_time_format_iso8601 (item->modified);
- visited = g_date_time_format_iso8601 (item->visited);
+ g_string_append (retval, " <" XBEL_BOOKMARK_ELEMENT " ");
escaped_uri = g_markup_escape_text (item->uri, -1);
- buffer = g_strconcat (" <"
- XBEL_BOOKMARK_ELEMENT
- " "
- XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" "
- XBEL_ADDED_ATTRIBUTE "=\"", added, "\" "
- XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" "
- XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n",
- NULL);
-
- g_string_append (retval, buffer);
+ g_string_append (retval, XBEL_HREF_ATTRIBUTE "=\"");
+ g_string_append (retval, escaped_uri);
+ g_string_append (retval , "\" ");
g_free (escaped_uri);
- g_free (visited);
- g_free (modified);
- g_free (added);
- g_free (buffer);
+
+ if (item->added)
+ {
+ char *added;
+
+ added = g_date_time_format_iso8601 (item->added);
+ g_string_append (retval, XBEL_ADDED_ATTRIBUTE "=\"");
+ g_string_append (retval, added);
+ g_string_append (retval, "\" ");
+ g_free (added);
+ }
+
+ if (item->modified)
+ {
+ char *modified;
+
+ modified = g_date_time_format_iso8601 (item->modified);
+ g_string_append (retval, XBEL_MODIFIED_ATTRIBUTE "=\"");
+ g_string_append (retval, modified);
+ g_string_append (retval, "\" ");
+ g_free (modified);
+ }
+
+ if (item->visited)
+ {
+ char *visited;
+
+ visited = g_date_time_format_iso8601 (item->visited);
+ g_string_append (retval, XBEL_VISITED_ATTRIBUTE "=\"");
+ g_string_append (retval, visited);
+ g_string_append (retval, "\" ");
+ g_free (visited);
+ }
+
+ if (retval->str[retval->len - 1] == ' ')
+ g_string_truncate (retval, retval->len - 1);
+ g_string_append (retval, ">\n");
if (item->title)
{
gchar *escaped_title;
escaped_title = g_markup_escape_text (item->title, -1);
- buffer = g_strconcat (" "
- "<" XBEL_TITLE_ELEMENT ">",
- escaped_title,
- "</" XBEL_TITLE_ELEMENT ">\n",
- NULL);
- g_string_append (retval, buffer);
+ g_string_append (retval, " " "<" XBEL_TITLE_ELEMENT ">");
+ g_string_append (retval, escaped_title);
+ g_string_append (retval, "</" XBEL_TITLE_ELEMENT ">\n");
g_free (escaped_title);
- g_free (buffer);
}
if (item->description)
@@ -611,15 +629,11 @@ bookmark_item_dump (BookmarkItem *item)
gchar *escaped_desc;
escaped_desc = g_markup_escape_text (item->description, -1);
- buffer = g_strconcat (" "
- "<" XBEL_DESC_ELEMENT ">",
- escaped_desc,
- "</" XBEL_DESC_ELEMENT ">\n",
- NULL);
- g_string_append (retval, buffer);
+ g_string_append (retval, " " "<" XBEL_DESC_ELEMENT ">");
+ g_string_append (retval, escaped_desc);
+ g_string_append (retval, "</" XBEL_DESC_ELEMENT ">\n");
g_free (escaped_desc);
- g_free (buffer);
}
if (item->metadata)
@@ -629,17 +643,12 @@ bookmark_item_dump (BookmarkItem *item)
metadata = bookmark_metadata_dump (item->metadata);
if (metadata)
{
- buffer = g_strconcat (" "
- "<" XBEL_INFO_ELEMENT ">\n",
- metadata,
- " "
- "</" XBEL_INFO_ELEMENT ">\n",
- NULL);
- retval = g_string_append (retval, buffer);
-
- g_free (buffer);
- g_free (metadata);
- }
+ g_string_append (retval, " " "<" XBEL_INFO_ELEMENT ">\n");
+ g_string_append (retval, metadata);
+ g_string_append (retval, " " "</" XBEL_INFO_ELEMENT ">\n");
+
+ g_free (metadata);
+ }
}
g_string_append (retval, " </" XBEL_BOOKMARK_ELEMENT ">\n");
diff --git a/glib/gbytes.c b/glib/gbytes.c
index aaadf451b..a6ca0e300 100644
--- a/glib/gbytes.c
+++ b/glib/gbytes.c
@@ -538,3 +538,75 @@ g_bytes_unref_to_array (GBytes *bytes)
data = g_bytes_unref_to_data (bytes, &size);
return g_byte_array_new_take (data, size);
}
+
+/**
+ * g_bytes_get_region:
+ * @bytes: a #GBytes
+ * @element_size: a non-zero element size
+ * @offset: an offset to the start of the region within the @bytes
+ * @n_elements: the number of elements in the region
+ *
+ * Gets a pointer to a region in @bytes.
+ *
+ * The region starts at @offset many bytes from the start of the data
+ * and contains @n_elements many elements of @element_size size.
+ *
+ * @n_elements may be zero, but @element_size must always be non-zero.
+ * Ideally, @element_size is a static constant (eg: sizeof a struct).
+ *
+ * This function does careful bounds checking (including checking for
+ * arithmetic overflows) and returns a non-%NULL pointer if the
+ * specified region lies entirely within the @bytes. If the region is
+ * in some way out of range, or if an overflow has occurred, then %NULL
+ * is returned.
+ *
+ * Note: it is possible to have a valid zero-size region. In this case,
+ * the returned pointer will be equal to the base pointer of the data of
+ * @bytes, plus @offset. This will be non-%NULL except for the case
+ * where @bytes itself was a zero-sized region. Since it is unlikely
+ * that you will be using this function to check for a zero-sized region
+ * in a zero-sized @bytes, %NULL effectively always means "error".
+ *
+ * Returns: (nullable): the requested region, or %NULL in case of an error
+ *
+ * Since: 2.70
+ */
+gconstpointer
+g_bytes_get_region (GBytes *bytes,
+ gsize element_size,
+ gsize offset,
+ gsize n_elements)
+{
+ gsize total_size;
+ gsize end_offset;
+
+ g_return_val_if_fail (element_size > 0, NULL);
+
+ /* No other assertion checks here. If something is wrong then we will
+ * simply crash (via NULL dereference or divide-by-zero).
+ */
+
+ if (!g_size_checked_mul (&total_size, element_size, n_elements))
+ return NULL;
+
+ if (!g_size_checked_add (&end_offset, offset, total_size))
+ return NULL;
+
+ /* We now have:
+ *
+ * 0 <= offset <= end_offset
+ *
+ * So we need only check that end_offset is within the range of the
+ * size of @bytes and we're good to go.
+ */
+
+ if (end_offset > bytes->size)
+ return NULL;
+
+ /* We now have:
+ *
+ * 0 <= offset <= end_offset <= bytes->size
+ */
+
+ return ((guchar *) bytes->data) + offset;
+} \ No newline at end of file
diff --git a/glib/gbytes.h b/glib/gbytes.h
index 0bb1517b9..37cad861d 100644
--- a/glib/gbytes.h
+++ b/glib/gbytes.h
@@ -85,6 +85,13 @@ GLIB_AVAILABLE_IN_ALL
gint g_bytes_compare (gconstpointer bytes1,
gconstpointer bytes2);
+GLIB_AVAILABLE_IN_2_70
+gconstpointer g_bytes_get_region (GBytes *bytes,
+ gsize element_size,
+ gsize offset,
+ gsize n_elements);
+
+
G_END_DECLS
#endif /* __G_BYTES_H__ */
diff --git a/glib/gcharset.c b/glib/gcharset.c
index bb775bda4..9f91a9b48 100644
--- a/glib/gcharset.c
+++ b/glib/gcharset.c
@@ -36,6 +36,12 @@
#include <string.h>
#include <stdio.h>
+
+#if (HAVE_LANGINFO_TIME_CODESET || HAVE_LANGINFO_CODESET)
+#include <langinfo.h>
+#endif
+
+#include <locale.h>
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -215,6 +221,87 @@ g_get_charset (const char **charset)
return cache->is_utf8;
}
+/*
+ * Do the same as g_get_charset() but it temporarily set locale (LC_ALL to
+ * LC_TIME) to correctly check for charset about time conversion relatives.
+ *
+ * Returns: %TRUE if the returned charset is UTF-8
+ */
+gboolean
+_g_get_time_charset (const char **charset)
+{
+ static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free);
+ GCharsetCache *cache = g_private_get (&cache_private);
+ const gchar *raw;
+
+ if (!cache)
+ cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache));
+
+#ifdef HAVE_LANGINFO_TIME_CODESET
+ raw = nl_langinfo (_NL_TIME_CODESET);
+#else
+ G_LOCK (aliases);
+ raw = _g_locale_charset_raw ();
+ G_UNLOCK (aliases);
+#endif
+
+ if (cache->raw == NULL || strcmp (cache->raw, raw) != 0)
+ {
+ const gchar *new_charset;
+
+ g_free (cache->raw);
+ g_free (cache->charset);
+ cache->raw = g_strdup (raw);
+ cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset);
+ cache->charset = g_strdup (new_charset);
+ }
+
+ if (charset)
+ *charset = cache->charset;
+
+ return cache->is_utf8;
+}
+/*
+ * Do the same as g_get_charset() but it temporarily set locale (LC_ALL to
+ * LC_CTYPE) to correctly check for charset about CTYPE conversion relatives.
+ *
+ * Returns: %TRUE if the returned charset is UTF-8
+ */
+gboolean
+_g_get_ctype_charset (const char **charset)
+{
+ static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free);
+ GCharsetCache *cache = g_private_get (&cache_private);
+ const gchar *raw;
+
+ if (!cache)
+ cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache));
+
+#ifdef HAVE_LANGINFO_CODESET
+ raw = nl_langinfo (CODESET);
+#else
+ G_LOCK (aliases);
+ raw = _g_locale_charset_raw ();
+ G_UNLOCK (aliases);
+#endif
+
+ if (cache->raw == NULL || strcmp (cache->raw, raw) != 0)
+ {
+ const gchar *new_charset;
+
+ g_free (cache->raw);
+ g_free (cache->charset);
+ cache->raw = g_strdup (raw);
+ cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset);
+ cache->charset = g_strdup (new_charset);
+ }
+
+ if (charset)
+ *charset = cache->charset;
+
+ return cache->is_utf8;
+}
+
/**
* g_get_codeset:
*
diff --git a/glib/gcharsetprivate.h b/glib/gcharsetprivate.h
index f6b68dcd7..9b1def278 100644
--- a/glib/gcharsetprivate.h
+++ b/glib/gcharsetprivate.h
@@ -25,6 +25,10 @@ G_BEGIN_DECLS
const char ** _g_charset_get_aliases (const char *canonical_name);
+gboolean _g_get_time_charset (const char **charset);
+
+gboolean _g_get_ctype_charset (const char **charset);
+
G_END_DECLS
#endif
diff --git a/glib/gconvert.c b/glib/gconvert.c
index f78cff01d..7697ff65d 100644
--- a/glib/gconvert.c
+++ b/glib/gconvert.c
@@ -40,6 +40,7 @@
#endif
#include "gconvert.h"
+#include "gconvertprivate.h"
#include "gcharsetprivate.h"
#include "gslist.h"
@@ -1015,6 +1016,52 @@ g_locale_to_utf8 (const gchar *opsysstring,
bytes_read, bytes_written, error);
}
+/*
+ * Do the exact same as g_locale_to_utf8 except that the charset would
+ * be retrieved from _g_get_time_charset (which uses LC_TIME)
+ *
+ * Returns: The converted string, or %NULL on an error.
+ */
+gchar *
+_g_time_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const char *charset;
+
+ if (_g_get_time_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return convert_checked (opsysstring, len, "UTF-8", charset,
+ CONVERT_CHECK_NO_NULS_IN_OUTPUT,
+ bytes_read, bytes_written, error);
+}
+
+/*
+ * Do the exact same as g_locale_to_utf8 except that the charset would
+ * be retrieved from _g_get_ctype_charset (which uses LC_CTYPE)
+ *
+ * Returns: The converted string, or %NULL on an error.
+ */
+gchar *
+_g_ctype_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const char *charset;
+
+ if (_g_get_ctype_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return convert_checked (opsysstring, len, "UTF-8", charset,
+ CONVERT_CHECK_NO_NULS_IN_OUTPUT,
+ bytes_read, bytes_written, error);
+}
+
/**
* g_locale_from_utf8:
* @utf8string: a UTF-8 encoded string
diff --git a/glib/gconvertprivate.h b/glib/gconvertprivate.h
new file mode 100644
index 000000000..5bdc87ff6
--- /dev/null
+++ b/glib/gconvertprivate.h
@@ -0,0 +1,40 @@
+/* gconvertprivate.h - Private GLib gconvert functions
+ *
+ * Copyright 2020 Frederic Martinsons
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __G_CONVERTPRIVATE_H__
+#define __G_CONVERTPRIVATE_H__
+
+G_BEGIN_DECLS
+
+#include "glib.h"
+
+gchar *_g_time_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+
+gchar *_g_ctype_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __G_CONVERTPRIVATE_H__ */
diff --git a/glib/gdate.c b/glib/gdate.c
index 253ab6524..6b36ae718 100644
--- a/glib/gdate.c
+++ b/glib/gdate.c
@@ -1206,6 +1206,22 @@ g_date_prepare_to_parse (const gchar *str,
g_date_fill_parse_tokens (str, pt);
}
+static guint
+convert_twodigit_year (guint y)
+{
+ if (using_twodigit_years && y < 100)
+ {
+ guint two = twodigit_start_year % 100;
+ guint century = (twodigit_start_year / 100) * 100;
+
+ if (y < two)
+ century += 100;
+
+ y += century;
+ }
+ return y;
+}
+
/**
* g_date_set_parse:
* @date: a #GDate to fill in
@@ -1302,16 +1318,8 @@ g_date_set_parse (GDate *d,
{
y += locale_era_adjust;
}
- else if (using_twodigit_years && y < 100)
- {
- guint two = twodigit_start_year % 100;
- guint century = (twodigit_start_year / 100) * 100;
-
- if (y < two)
- century += 100;
-
- y += century;
- }
+
+ y = convert_twodigit_year (y);
}
break;
default:
@@ -1355,18 +1363,8 @@ g_date_set_parse (GDate *d,
m = (pt.n[0]/100) % 100;
day = pt.n[0] % 100;
y = pt.n[0]/10000;
-
- /* FIXME move this into a separate function */
- if (using_twodigit_years && y < 100)
- {
- guint two = twodigit_start_year % 100;
- guint century = (twodigit_start_year / 100) * 100;
-
- if (y < two)
- century += 100;
-
- y += century;
- }
+
+ y = convert_twodigit_year (y);
}
}
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index ffdeddd81..a31afe713 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -60,23 +60,23 @@
#include <langinfo.h>
#endif
-#include "gdatetime.h"
-
-#include "gslice.h"
#include "gatomic.h"
#include "gcharset.h"
+#include "gcharsetprivate.h"
#include "gconvert.h"
+#include "gconvertprivate.h"
+#include "gdatetime.h"
#include "gfileutils.h"
#include "ghash.h"
+#include "glibintl.h"
#include "gmain.h"
#include "gmappedfile.h"
+#include "gslice.h"
#include "gstrfuncs.h"
#include "gtestutils.h"
#include "gthread.h"
#include "gtimezone.h"
-#include "glibintl.h"
-
#ifndef G_OS_WIN32
#include <sys/time.h>
#include <time.h>
@@ -2871,7 +2871,7 @@ initialize_alt_digits (void)
if (g_strcmp0 (locale_digit, "") == 0)
return NULL;
- digit = g_locale_to_utf8 (locale_digit, -1, NULL, &digit_len, NULL);
+ digit = _g_ctype_locale_to_utf8 (locale_digit, -1, NULL, &digit_len, NULL);
if (digit == NULL)
return NULL;
@@ -2995,7 +2995,7 @@ g_date_time_format_locale (GDateTime *datetime,
if (locale_is_utf8)
return g_date_time_format_utf8 (datetime, locale_format, outstr, locale_is_utf8);
- utf8_format = g_locale_to_utf8 (locale_format, -1, NULL, NULL, NULL);
+ utf8_format = _g_time_locale_to_utf8 (locale_format, -1, NULL, NULL, NULL);
if (utf8_format == NULL)
return FALSE;
@@ -3019,7 +3019,7 @@ string_append (GString *string,
}
else
{
- utf8 = g_locale_to_utf8 (s, -1, NULL, &utf8_len, NULL);
+ utf8 = _g_time_locale_to_utf8 (s, -1, NULL, &utf8_len, NULL);
if (utf8 == NULL)
return FALSE;
g_string_append_len (string, utf8, utf8_len);
@@ -3445,10 +3445,11 @@ g_date_time_format (GDateTime *datetime,
{
GString *outstr;
const gchar *charset;
- /* Avoid conversions from locale charset to UTF-8 if charset is compatible
+ /* Avoid conversions from locale (for LC_TIME and not for LC_MESSAGES unless
+ * specified otherwise) charset to UTF-8 if charset is compatible
* with UTF-8 already. Check for UTF-8 and synonymous canonical names of
* ASCII. */
- gboolean locale_is_utf8_compatible = g_get_charset (&charset) ||
+ gboolean time_is_utf8_compatible = _g_get_time_charset (&charset) ||
g_strcmp0 ("ASCII", charset) == 0 ||
g_strcmp0 ("ANSI_X3.4-1968", charset) == 0;
@@ -3459,7 +3460,7 @@ g_date_time_format (GDateTime *datetime,
outstr = g_string_sized_new (strlen (format) * 2);
if (!g_date_time_format_utf8 (datetime, format, outstr,
- locale_is_utf8_compatible))
+ time_is_utf8_compatible))
{
g_string_free (outstr, TRUE);
return NULL;
diff --git a/glib/gdir.c b/glib/gdir.c
index c26edc1dc..b07eb5c20 100644
--- a/glib/gdir.c
+++ b/glib/gdir.c
@@ -60,7 +60,9 @@ struct _GDir
DIR *dirp;
#endif
#ifdef G_OS_WIN32
- gchar utf8_buf[FILENAME_MAX*4];
+ /* maximum encoding of FILENAME_MAX UTF-8 characters, plus a nul terminator
+ * (FILENAME_MAX is not guaranteed to include one) */
+ gchar utf8_buf[FILENAME_MAX*4 + 1];
#endif
};
diff --git a/glib/gerror.c b/glib/gerror.c
index 82bf626ed..bd5408872 100644
--- a/glib/gerror.c
+++ b/glib/gerror.c
@@ -114,6 +114,12 @@
* function (the file being opened, or whatever - though in the
* g_file_get_contents() case, the @message already contains a filename).
*
+ * Since error messages may be displayed to the user, they need to be valid
+ * UTF-8 (all GTK widgets expect text to be UTF-8). Keep this in mind in
+ * particular when formatting error messages with filenames, which are in
+ * the 'filename encoding', and need to be turned into UTF-8 using
+ * g_filename_to_utf8(), g_filename_display_name() or g_utf8_make_valid().
+ *
* Note, however, that many error messages are too technical to display to the
* user in an application, so prefer to use g_error_matches() to categorize errors
* from called functions, and build an appropriate error message for the context
@@ -1095,6 +1101,30 @@ g_prefix_error (GError **err,
}
/**
+ * g_prefix_error_literal:
+ * @err: (allow-none): a return location for a #GError, or %NULL
+ * @prefix: string to prefix @err with
+ *
+ * Prefixes @prefix to an existing error message. If @err or *@err is
+ * %NULL (i.e.: no error variable) then do nothing.
+ *
+ * Since: 2.70
+ */
+void
+g_prefix_error_literal (GError **err,
+ const gchar *prefix)
+{
+ if (err && *err)
+ {
+ gchar *oldstring;
+
+ oldstring = (*err)->message;
+ (*err)->message = g_strconcat (prefix, oldstring, NULL);
+ g_free (oldstring);
+ }
+}
+
+/**
* g_propagate_prefixed_error:
* @dest: error return location
* @src: error to move into the return location
diff --git a/glib/gerror.h b/glib/gerror.h
index 6431d5b6c..bc9c03a91 100644
--- a/glib/gerror.h
+++ b/glib/gerror.h
@@ -244,6 +244,11 @@ void g_prefix_error (GError **err,
const gchar *format,
...) G_GNUC_PRINTF (2, 3);
+/* if (err) prefix the string to the ->message */
+GLIB_AVAILABLE_IN_2_70
+void g_prefix_error_literal (GError **err,
+ const gchar *prefix);
+
/* g_propagate_error then g_error_prefix on dest */
GLIB_AVAILABLE_IN_ALL
void g_propagate_prefixed_error (GError **dest,
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index a4e90265e..e0a2a65d0 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -1208,14 +1208,6 @@ write_to_file (const gchar *contents,
return TRUE;
}
-static inline int
-steal_fd (int *fd_ptr)
-{
- int fd = *fd_ptr;
- *fd_ptr = -1;
- return fd;
-}
-
/**
* g_file_set_contents:
* @filename: (type filename): name of a file to write @contents to, in the GLib file name
@@ -1369,7 +1361,7 @@ g_file_set_contents_full (const gchar *filename,
}
do_fsync = fd_should_be_fsynced (fd, filename, flags);
- if (!write_to_file (contents, length, steal_fd (&fd), tmp_filename, do_fsync, error))
+ if (!write_to_file (contents, length, g_steal_fd (&fd), tmp_filename, do_fsync, error))
{
g_unlink (tmp_filename);
retval = FALSE;
@@ -1479,7 +1471,7 @@ consistent_out:
}
do_fsync = fd_should_be_fsynced (direct_fd, filename, flags);
- if (!write_to_file (contents, length, steal_fd (&direct_fd), filename,
+ if (!write_to_file (contents, length, g_steal_fd (&direct_fd), filename,
do_fsync, error))
return FALSE;
}
diff --git a/glib/ghash.c b/glib/ghash.c
index cc2d00087..48a7db0e2 100644
--- a/glib/ghash.c
+++ b/glib/ghash.c
@@ -2191,7 +2191,7 @@ g_hash_table_get_keys (GHashTable *hash_table)
/**
* g_hash_table_get_keys_as_array:
* @hash_table: a #GHashTable
- * @length: (out): the length of the returned array
+ * @length: (out) (optional): the length of the returned array
*
* Retrieves every key inside @hash_table, as an array.
*
diff --git a/glib/glib-typeof.h b/glib/glib-typeof.h
new file mode 100644
index 000000000..198901c29
--- /dev/null
+++ b/glib/glib-typeof.h
@@ -0,0 +1,43 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2021 Iain Lane, Xavier Claessens
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GLIB_TYPEOF_H__
+#define __GLIB_TYPEOF_H__
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#include <glib/gversionmacros.h>
+
+/*
+ * We can only use __typeof__ on GCC >= 4.8, and not when compiling C++. Since
+ * __typeof__ is used in a few places in GLib, provide a pre-processor symbol
+ * to factor the check out from callers.
+ *
+ * This symbol is private.
+ */
+#undef glib_typeof
+#if !defined(__cplusplus) && (G_GNUC_CHECK_VERSION(4, 8) || defined(__clang__))
+#define glib_typeof(t) __typeof__ (t)
+#elif defined(__cplusplus) && __cplusplus >= 201103L && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
+/* C++11 decltype() is close enough for our usage */
+#include <type_traits>
+#define glib_typeof(t) typename std::remove_reference<decltype (t)>::type
+#endif
+
+#endif /* __GLIB_TYPEOF_H__ */
diff --git a/glib/glib.h b/glib/glib.h
index a4d43a9bf..e72c09da5 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -112,6 +112,7 @@
#include <glib/deprecated/gthread.h>
#include <glib/glib-autocleanups.h>
+#include <glib/glib-typeof.h>
#undef __GLIB_H_INSIDE__
diff --git a/glib/gmacros.h b/glib/gmacros.h
index 42e3c66c7..27c2c48ac 100644
--- a/glib/gmacros.h
+++ b/glib/gmacros.h
@@ -37,6 +37,12 @@
*/
#include <stddef.h>
+/*
+ * Note: Clang (but not clang-cl) defines __GNUC__ and __GNUC_MINOR__.
+ * Both Clang 11.1 on current Arch Linux and Apple's Clang 12.0 define
+ * __GNUC__ = 4 and __GNUC_MINOR__ = 2. So G_GNUC_CHECK_VERSION(4, 2) on
+ * current Clang will be 1.
+ */
#ifdef __GNUC__
#define G_GNUC_CHECK_VERSION(major, minor) \
((__GNUC__ > (major)) || \
@@ -50,7 +56,7 @@
* where this is valid. This allows for warningless compilation of
* "long long" types even in the presence of '-ansi -pedantic'.
*/
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+#if G_GNUC_CHECK_VERSION(2, 8)
#define G_GNUC_EXTENSION __extension__
#else
#define G_GNUC_EXTENSION
@@ -106,6 +112,39 @@
# define G_INLINE_FUNC static inline GLIB_DEPRECATED_MACRO_IN_2_48_FOR(static inline)
#endif /* G_IMPLEMENT_INLINES */
+/*
+ * Attribute support detection. Works on clang and GCC >= 5
+ * https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ * https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html
+ */
+
+#ifdef __has_attribute
+#define g_macro__has_attribute __has_attribute
+#else
+
+/*
+ * Fallback for GCC < 5 and other compilers not supporting __has_attribute.
+ */
+#define g_macro__has_attribute(x) g_macro__has_attribute_##x
+
+#define g_macro__has_attribute___pure__ G_GNUC_CHECK_VERSION (2, 96)
+#define g_macro__has_attribute___malloc__ G_GNUC_CHECK_VERSION (2, 96)
+#define g_macro__has_attribute___noinline__ G_GNUC_CHECK_VERSION (2, 96)
+#define g_macro__has_attribute___sentinel__ G_GNUC_CHECK_VERSION (4, 0)
+#define g_macro__has_attribute___alloc_size__ G_GNUC_CHECK_VERSION (4, 3)
+#define g_macro__has_attribute___format__ G_GNUC_CHECK_VERSION (2, 4)
+#define g_macro__has_attribute___format_arg__ G_GNUC_CHECK_VERSION (2, 4)
+#define g_macro__has_attribute___noreturn__ (G_GNUC_CHECK_VERSION (2, 8) || (0x5110 <= __SUNPRO_C))
+#define g_macro__has_attribute___const__ G_GNUC_CHECK_VERSION (2, 4)
+#define g_macro__has_attribute___unused__ G_GNUC_CHECK_VERSION (2, 4)
+#define g_macro__has_attribute___no_instrument_function__ G_GNUC_CHECK_VERSION (2, 4)
+#define g_macro__has_attribute_fallthrough G_GNUC_CHECK_VERSION (6, 0)
+#define g_macro__has_attribute___deprecated__ G_GNUC_CHECK_VERSION (3, 1)
+#define g_macro__has_attribute_may_alias G_GNUC_CHECK_VERSION (3, 3)
+#define g_macro__has_attribute_warn_unused_result G_GNUC_CHECK_VERSION (3, 4)
+
+#endif
+
/* Provide macros to feature the GCC function attribute.
*/
@@ -188,14 +227,27 @@
*
* Since: 2.58
*/
+/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_58 because it’s
+ * used within the GLib headers in function declarations which are always
+ * evaluated when a header is included. This results in warnings in third party
+ * code which includes glib.h, even if the third party code doesn’t use the new
+ * macro itself. */
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+#if g_macro__has_attribute(__pure__)
#define G_GNUC_PURE __attribute__((__pure__))
-#define G_GNUC_MALLOC __attribute__((__malloc__))
-#define G_GNUC_NO_INLINE __attribute__((noinline))
#else
#define G_GNUC_PURE
+#endif
+
+#if g_macro__has_attribute(__malloc__)
+#define G_GNUC_MALLOC __attribute__ ((__malloc__))
+#else
#define G_GNUC_MALLOC
+#endif
+
+#if g_macro__has_attribute(__noinline__)
+#define G_GNUC_NO_INLINE __attribute__ ((__noinline__))
+#else
#define G_GNUC_NO_INLINE
#endif
@@ -218,37 +270,13 @@
*
* Since: 2.8
*/
-#if __GNUC__ >= 4
+#if g_macro__has_attribute(__sentinel__)
#define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
#else
#define G_GNUC_NULL_TERMINATED
#endif
/*
- * We can only use __typeof__ on GCC >= 4.8, and not when compiling C++. Since
- * __typeof__ is used in a few places in GLib, provide a pre-processor symbol
- * to factor the check out from callers.
- *
- * This symbol is private.
- */
-#undef glib_typeof
-#if !defined(__cplusplus) && \
- ((defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
- defined(__clang__))
-#define glib_typeof(t) __typeof__ (t)
-#elif defined(__cplusplus) && __cplusplus >= 201103L
-/* C++11 decltype() is close enough for our usage */
-/* This needs `#include <type_traits>`, but we have guarded this feature with a
- * `GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68` check, and such a check
- * cannot be enforced in this header due to include ordering requirements.
- * Within GLib itself, which use `glib_typeof` need to add the include
- * themselves. See other examples in GLib for how to do this.
- */
-#define glib_typeof(t) typename std::remove_reference<decltype (t)>::type
-#define glib_typeof_2_68
-#endif
-
-/*
* Clang feature detection: http://clang.llvm.org/docs/LanguageExtensions.html
* These are not available on GCC, but since the pre-processor doesn't do
* operator short-circuiting, we can't use it in a statement or we'll get:
@@ -258,12 +286,6 @@
* So we define it to 0 to satisfy the pre-processor.
*/
-#ifdef __has_attribute
-#define g_macro__has_attribute __has_attribute
-#else
-#define g_macro__has_attribute(x) 0
-#endif
-
#ifdef __has_feature
#define g_macro__has_feature __has_feature
#else
@@ -276,6 +298,12 @@
#define g_macro__has_builtin(x) 0
#endif
+#ifdef __has_extension
+#define g_macro__has_extension __has_extension
+#else
+#define g_macro__has_extension(x) 0
+#endif
+
/**
* G_GNUC_ALLOC_SIZE:
* @x: the index of the argument specifying the allocation size
@@ -319,8 +347,7 @@
*
* Since: 2.18
*/
-#if (!defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
- (defined(__clang__) && g_macro__has_attribute(__alloc_size__))
+#if g_macro__has_attribute(__alloc_size__)
#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
#else
@@ -506,46 +533,73 @@
* See the [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005finstrument_005ffunction-function-attribute) for more details.
*/
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#if g_macro__has_attribute(__format__)
+
#if !defined (__clang__) && G_GNUC_CHECK_VERSION (4, 4)
#define G_GNUC_PRINTF( format_idx, arg_idx ) \
__attribute__((__format__ (gnu_printf, format_idx, arg_idx)))
#define G_GNUC_SCANF( format_idx, arg_idx ) \
__attribute__((__format__ (gnu_scanf, format_idx, arg_idx)))
#define G_GNUC_STRFTIME( format_idx ) \
- __attribute__((__format__ (gnu_strftime, format_idx, 0)))
+ __attribute__((__format__ (gnu_strftime, format_idx, 0))) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
#else
#define G_GNUC_PRINTF( format_idx, arg_idx ) \
__attribute__((__format__ (__printf__, format_idx, arg_idx)))
#define G_GNUC_SCANF( format_idx, arg_idx ) \
__attribute__((__format__ (__scanf__, format_idx, arg_idx)))
#define G_GNUC_STRFTIME( format_idx ) \
- __attribute__((__format__ (__strftime__, format_idx, 0)))
+ __attribute__((__format__ (__strftime__, format_idx, 0))) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
#endif
-#define G_GNUC_FORMAT( arg_idx ) \
- __attribute__((__format_arg__ (arg_idx)))
-#define G_GNUC_NORETURN \
- __attribute__((__noreturn__))
-#define G_GNUC_CONST \
- __attribute__((__const__))
-#define G_GNUC_UNUSED \
- __attribute__((__unused__))
-#define G_GNUC_NO_INSTRUMENT \
- __attribute__((__no_instrument_function__))
-#else /* !__GNUC__ */
+
+#else
+
#define G_GNUC_PRINTF( format_idx, arg_idx )
#define G_GNUC_SCANF( format_idx, arg_idx )
-#define G_GNUC_STRFTIME( format_idx )
+#define G_GNUC_STRFTIME( format_idx ) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
+
+#endif
+
+#if g_macro__has_attribute(__format_arg__)
+#define G_GNUC_FORMAT(arg_idx) \
+ __attribute__ ((__format_arg__ (arg_idx)))
+#else
#define G_GNUC_FORMAT( arg_idx )
+#endif
+
+#if g_macro__has_attribute(__noreturn__)
+#define G_GNUC_NORETURN \
+ __attribute__ ((__noreturn__))
+#else
/* NOTE: MSVC has __declspec(noreturn) but unlike GCC __attribute__,
* __declspec can only be placed at the start of the function prototype
* and not at the end, so we can't use it without breaking API.
*/
#define G_GNUC_NORETURN
+#endif
+
+#if g_macro__has_attribute(__const__)
+#define G_GNUC_CONST \
+ __attribute__ ((__const__))
+#else
#define G_GNUC_CONST
+#endif
+
+#if g_macro__has_attribute(__unused__)
+#define G_GNUC_UNUSED \
+ __attribute__ ((__unused__))
+#else
#define G_GNUC_UNUSED
+#endif
+
+#if g_macro__has_attribute(__no_instrument_function__)
+#define G_GNUC_NO_INSTRUMENT \
+ __attribute__ ((__no_instrument_function__))
+#else
#define G_GNUC_NO_INSTRUMENT
-#endif /* !__GNUC__ */
+#endif
/**
* G_GNUC_FALLTHROUGH:
@@ -575,13 +629,13 @@
*
* Since: 2.60
*/
-#if __GNUC__ > 6
-#define G_GNUC_FALLTHROUGH __attribute__((fallthrough))
-#elif g_macro__has_attribute (fallthrough)
-#define G_GNUC_FALLTHROUGH __attribute__((fallthrough))
+#if g_macro__has_attribute(fallthrough)
+#define G_GNUC_FALLTHROUGH __attribute__((fallthrough)) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
#else
-#define G_GNUC_FALLTHROUGH
-#endif /* __GNUC__ */
+#define G_GNUC_FALLTHROUGH \
+ GLIB_AVAILABLE_MACRO_IN_2_60
+#endif
/**
* G_GNUC_DEPRECATED:
@@ -601,7 +655,7 @@
*
* Since: 2.2
*/
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || defined (__clang__)
+#if g_macro__has_attribute(__deprecated__)
#define G_GNUC_DEPRECATED __attribute__((__deprecated__))
#else
#define G_GNUC_DEPRECATED
@@ -630,11 +684,13 @@
*
* Since: 2.26
*/
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || defined (__clang__)
+#if G_GNUC_CHECK_VERSION(4, 5) || defined(__clang__)
#define G_GNUC_DEPRECATED_FOR(f) \
- __attribute__((deprecated("Use " #f " instead")))
+ __attribute__((deprecated("Use " #f " instead"))) \
+ GLIB_AVAILABLE_MACRO_IN_2_26
#else
-#define G_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED
+#define G_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED \
+ GLIB_AVAILABLE_MACRO_IN_2_26
#endif /* __GNUC__ */
#ifdef __ICC
@@ -643,7 +699,7 @@
_Pragma ("warning (disable:1478)")
#define G_GNUC_END_IGNORE_DEPRECATIONS \
_Pragma ("warning (pop)")
-#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#elif G_GNUC_CHECK_VERSION(4, 6)
#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
@@ -677,7 +733,7 @@
*
* Since: 2.14
*/
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#if g_macro__has_attribute(may_alias)
#define G_GNUC_MAY_ALIAS __attribute__((may_alias))
#else
#define G_GNUC_MAY_ALIAS
@@ -701,7 +757,7 @@
*
* Since: 2.10
*/
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#if g_macro__has_attribute(warn_unused_result)
#define G_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define G_GNUC_WARN_UNUSED_RESULT
@@ -743,6 +799,9 @@
#if g_macro__has_feature(attribute_analyzer_noreturn) && defined(__clang_analyzer__)
#define G_ANALYZER_ANALYZING 1
#define G_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+#elif defined(__COVERITY__)
+#define G_ANALYZER_ANALYZING 1
+#define G_ANALYZER_NORETURN __attribute__((noreturn))
#else
#define G_ANALYZER_ANALYZING 0
#define G_ANALYZER_NORETURN
@@ -754,7 +813,8 @@
#ifndef __GI_SCANNER__ /* The static assert macro really confuses the introspection parser */
#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
#define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2)
-#if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#if !defined(__cplusplus) && defined(__STDC_VERSION__) && \
+ (__STDC_VERSION__ >= 201112L || g_macro__has_feature(c_static_assert) || g_macro__has_extension(c_static_assert))
#define G_STATIC_ASSERT(expr) _Static_assert (expr, "Expression evaluates to false")
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
@@ -848,7 +908,7 @@
* fields through their offsets.
*/
-#if (defined(__GNUC__) && __GNUC__ >= 4) || defined (_MSC_VER)
+#if G_GNUC_CHECK_VERSION(4, 0) || defined(_MSC_VER)
#define G_STRUCT_OFFSET(struct_type, member) \
((glong) offsetof (struct_type, member))
#else
@@ -907,9 +967,11 @@
* Since: 2.60
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
-#define G_ALIGNOF(type) _Alignof (type)
+#define G_ALIGNOF(type) _Alignof (type) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
#else
-#define G_ALIGNOF(type) (G_STRUCT_OFFSET (struct { char a; type b; }, b))
+#define G_ALIGNOF(type) (G_STRUCT_OFFSET (struct { char a; type b; }, b)) \
+ GLIB_AVAILABLE_MACRO_IN_2_60
#endif
/**
@@ -956,7 +1018,7 @@
* evaluated when a header is included. This results in warnings in third party
* code which includes glib.h, even if the third party code doesn’t use the new
* macro itself. */
-#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) || (0x5110 <= __SUNPRO_C)
+#if g_macro__has_attribute(__noreturn__)
/* For compatibility with G_NORETURN_FUNCPTR on clang, use
__attribute__((__noreturn__)), not _Noreturn. */
# define G_NORETURN __attribute__ ((__noreturn__))
@@ -964,10 +1026,10 @@
/* Use MSVC specific syntax. */
# define G_NORETURN __declspec (noreturn)
/* Use ISO C++11 syntax when the compiler supports it. */
-#elif (defined (__cplusplus) && __cplusplus >= 201103 && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) || defined (_MSC_VER) && (_MSC_VER >= 1900)
+#elif defined (__cplusplus) && __cplusplus >= 201103
# define G_NORETURN [[noreturn]]
/* Use ISO C11 syntax when the compiler supports it. */
-#elif (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
+#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112
# define G_NORETURN _Noreturn
#else
# define G_NORETURN /* empty */
@@ -995,7 +1057,7 @@
*
* Since: 2.68
*/
-#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) || (0x5110 <= __SUNPRO_C)
+#if g_macro__has_attribute(__noreturn__)
# define G_NORETURN_FUNCPTR __attribute__ ((__noreturn__)) \
GLIB_AVAILABLE_MACRO_IN_2_68
#else
@@ -1011,7 +1073,7 @@
* The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when
* putting assignments in g_return_if_fail ().
*/
-#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#if G_GNUC_CHECK_VERSION(2, 0) && defined(__OPTIMIZE__)
#define _G_BOOLEAN_EXPR(expr) \
G_GNUC_EXTENSION ({ \
int _g_boolean_var_; \
@@ -1028,7 +1090,7 @@
#define G_UNLIKELY(expr) (expr)
#endif
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || defined (__clang__)
+#if G_GNUC_CHECK_VERSION(3, 1) || defined(__clang__)
#define G_DEPRECATED __attribute__((__deprecated__))
#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
#define G_DEPRECATED __declspec(deprecated)
@@ -1036,7 +1098,7 @@
#define G_DEPRECATED
#endif
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || defined (__clang__)
+#if G_GNUC_CHECK_VERSION(4, 5) || defined(__clang__)
#define G_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
#define G_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
@@ -1044,7 +1106,7 @@
#define G_DEPRECATED_FOR(f) G_DEPRECATED
#endif
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || defined (__clang__)
+#if G_GNUC_CHECK_VERSION(4, 5) || defined(__clang__)
#define G_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available before " #maj "." #min)))
#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
#define G_UNAVAILABLE(maj,min) __declspec(deprecated("is not available before " #maj "." #min))
@@ -1075,12 +1137,14 @@
#endif
#if !defined(GLIB_DISABLE_DEPRECATION_WARNINGS) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || \
+ (G_GNUC_CHECK_VERSION(4, 6) || \
__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4))
#define _GLIB_GNUC_DO_PRAGMA(x) _Pragma(G_STRINGIFY (x))
#define GLIB_DEPRECATED_MACRO _GLIB_GNUC_DO_PRAGMA(GCC warning "Deprecated pre-processor symbol")
-#define GLIB_DEPRECATED_MACRO_FOR(f) _GLIB_GNUC_DO_PRAGMA(GCC warning "Deprecated pre-processor symbol, replace with " #f)
-#define GLIB_UNAVAILABLE_MACRO(maj,min) _GLIB_GNUC_DO_PRAGMA(GCC warning "Not available before " #maj "." #min)
+#define GLIB_DEPRECATED_MACRO_FOR(f) \
+ _GLIB_GNUC_DO_PRAGMA(GCC warning G_STRINGIFY (Deprecated pre-processor symbol: replace with #f))
+#define GLIB_UNAVAILABLE_MACRO(maj,min) \
+ _GLIB_GNUC_DO_PRAGMA(GCC warning G_STRINGIFY (Not available before maj.min))
#else
#define GLIB_DEPRECATED_MACRO
#define GLIB_DEPRECATED_MACRO_FOR(f)
@@ -1088,7 +1152,7 @@
#endif
#if !defined(GLIB_DISABLE_DEPRECATION_WARNINGS) && \
- ((defined (__GNUC__) && (__GNUC__ > 6 || (__GNUC__ == 6 && __GNUC_MINOR__ >= 1))) || \
+ (G_GNUC_CHECK_VERSION(6, 1) || \
(defined (__clang_major__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 0))))
#define GLIB_DEPRECATED_ENUMERATOR G_DEPRECATED
#define GLIB_DEPRECATED_ENUMERATOR_FOR(f) G_DEPRECATED_FOR(f)
@@ -1100,7 +1164,7 @@
#endif
#if !defined(GLIB_DISABLE_DEPRECATION_WARNINGS) && \
- ((defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) || \
+ (G_GNUC_CHECK_VERSION(3, 1) || \
(defined (__clang_major__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 0))))
#define GLIB_DEPRECATED_TYPE G_DEPRECATED
#define GLIB_DEPRECATED_TYPE_FOR(f) G_DEPRECATED_FOR(f)
diff --git a/glib/gmain.c b/glib/gmain.c
index 15581ee7a..4efa9ad6f 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -1370,6 +1370,10 @@ g_source_destroy_internal (GSource *source,
*
* This function is safe to call from any thread, regardless of which thread
* the #GMainContext is running in.
+ *
+ * If the source is currently attached to a #GMainContext, destroying it
+ * will effectively unset the callback similar to calling g_source_set_callback().
+ * This can mean, that the data's #GDestroyNotify gets called right away.
*/
void
g_source_destroy (GSource *source)
@@ -1761,6 +1765,9 @@ g_source_set_callback_indirect (GSource *source,
* It is safe to call this function multiple times on a source which has already
* been attached to a context. The changes will take effect for the next time
* the source is dispatched after this call returns.
+ *
+ * Note that g_source_destroy() for a currently attached source has the effect
+ * of also unsetting the callback.
**/
void
g_source_set_callback (GSource *source,
@@ -5723,7 +5730,7 @@ g_child_watch_source_new (GPid pid)
* you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
* the spawn function for the child watching to work.
*
- * In many programs, you will want to call g_spawn_check_exit_status()
+ * In many programs, you will want to call g_spawn_check_wait_status()
* in the callback to determine whether or not the child exited
* successfully.
*
@@ -6122,3 +6129,23 @@ g_get_worker_context (void)
return glib_worker_context;
}
+
+/**
+ * g_steal_fd:
+ * @fd_ptr: (not optional) (inout): A pointer to a file descriptor
+ *
+ * Sets @fd_ptr to `-1`, returning the value that was there before.
+ *
+ * Conceptually, this transfers the ownership of the file descriptor
+ * from the referenced variable to the caller of the function (i.e.
+ * ‘steals’ the reference). This is very similar to g_steal_pointer(),
+ * but for file descriptors.
+ *
+ * On POSIX platforms, this function is async-signal safe
+ * (see [`signal(7)`](man:signal(7)) and
+ * [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
+ * signal handler or a #GSpawnChildSetupFunc.
+ *
+ * Returns: the value that @fd_ptr previously had
+ * Since: 2.70
+ */
diff --git a/glib/gmain.h b/glib/gmain.h
index 5c0e524cc..8428e01a4 100644
--- a/glib/gmain.h
+++ b/glib/gmain.h
@@ -193,16 +193,20 @@ typedef gboolean (*GSourceFunc) (gpointer user_data);
/**
* GChildWatchFunc:
* @pid: the process id of the child process
- * @status: Status information about the child process, encoded
- * in a platform-specific manner
+ * @wait_status: Status information about the child process, encoded
+ * in a platform-specific manner
* @user_data: user data passed to g_child_watch_add()
*
* Prototype of a #GChildWatchSource callback, called when a child
- * process has exited. To interpret @status, see the documentation
- * for g_spawn_check_exit_status().
+ * process has exited.
+ *
+ * To interpret @wait_status, see the documentation
+ * for g_spawn_check_wait_status(). In particular,
+ * on Unix platforms, note that it is usually not equal
+ * to the integer passed to `exit()` or returned from `main()`.
*/
typedef void (*GChildWatchFunc) (GPid pid,
- gint status,
+ gint wait_status,
gpointer user_data);
@@ -264,8 +268,8 @@ typedef void (*GSourceDummyMarshal) (void);
struct _GSourceFuncs
{
gboolean (*prepare) (GSource *source,
- gint *timeout_);
- gboolean (*check) (GSource *source);
+ gint *timeout_);/* Can be NULL */
+ gboolean (*check) (GSource *source);/* Can be NULL */
gboolean (*dispatch) (GSource *source,
GSourceFunc callback,
gpointer user_data);
@@ -781,6 +785,15 @@ void g_main_context_invoke (GMainContext *context,
GSourceFunc function,
gpointer data);
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
+static inline int
+g_steal_fd (int *fd_ptr)
+{
+ int fd = *fd_ptr;
+ *fd_ptr = -1;
+ return fd;
+}
+
/* Hook for GClosure / GSource integration. Don't touch */
GLIB_VAR GSourceFuncs g_timeout_funcs;
GLIB_VAR GSourceFuncs g_child_watch_funcs;
diff --git a/glib/gmem.h b/glib/gmem.h
index ccf477843..47c4735ac 100644
--- a/glib/gmem.h
+++ b/glib/gmem.h
@@ -30,11 +30,7 @@
#endif
#include <glib/gutils.h>
-
-#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
-/* for glib_typeof */
-#include <type_traits>
-#endif
+#include <glib/glib-typeof.h>
G_BEGIN_DECLS
@@ -115,7 +111,7 @@ gpointer g_try_realloc_n (gpointer mem,
gsize n_blocks,
gsize n_block_bytes) G_GNUC_WARN_UNUSED_RESULT;
-#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58
#define g_clear_pointer(pp, destroy) \
G_STMT_START \
{ \
@@ -218,7 +214,7 @@ g_steal_pointer (gpointer pp)
}
/* type safety */
-#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58
#define g_steal_pointer(pp) ((glib_typeof (*pp)) (g_steal_pointer) (pp))
#else /* __GNUC__ */
/* This version does not depend on gcc extensions, but gcc does not warn
diff --git a/glib/goption.c b/glib/goption.c
index a351f84cb..8cb72376c 100644
--- a/glib/goption.c
+++ b/glib/goption.c
@@ -102,7 +102,7 @@
* { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
* { "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL },
* { "rand", 0, 0, G_OPTION_ARG_NONE, &randomize, "Randomize the data", NULL },
- * { NULL }
+ * G_OPTION_ENTRY_NULL
* };
*
* int
@@ -1543,23 +1543,14 @@ parse_short_option (GOptionContext *context,
if (idx < *argc - 1)
{
- if (!OPTIONAL_ARG (&group->entries[j]))
+ if (OPTIONAL_ARG (&group->entries[j]) && ((*argv)[idx + 1][0] == '-'))
+ value = NULL;
+ else
{
value = (*argv)[idx + 1];
add_pending_null (context, &((*argv)[idx + 1]), NULL);
*new_idx = idx + 1;
}
- else
- {
- if ((*argv)[idx + 1][0] == '-')
- value = NULL;
- else
- {
- value = (*argv)[idx + 1];
- add_pending_null (context, &((*argv)[idx + 1]), NULL);
- *new_idx = idx + 1;
- }
- }
}
else if (idx >= *argc - 1 && OPTIONAL_ARG (&group->entries[j]))
value = NULL;
diff --git a/glib/goption.h b/glib/goption.h
index 63552fb0d..44815a77d 100644
--- a/glib/goption.h
+++ b/glib/goption.h
@@ -286,6 +286,24 @@ struct _GOptionEntry
*/
#define G_OPTION_REMAINING ""
+/**
+ * G_OPTION_ENTRY_NULL:
+ *
+ * A #GOptionEntry array requires a %NULL terminator, this macro can
+ * be used as terminator instead of an explicit `{ 0 }` but it cannot
+ * be assigned to a variable.
+ *
+ * |[
+ * GOptionEntry option[] = { G_OPTION_ENTRY_NULL };
+ * ]|
+ *
+ * Since: 2.70
+ */
+#define G_OPTION_ENTRY_NULL \
+ GLIB_AVAILABLE_MACRO_IN_2_70 \
+ { NULL, 0, 0, 0, NULL, NULL, NULL }
+
+
GLIB_AVAILABLE_IN_ALL
GOptionContext *g_option_context_new (const gchar *parameter_string);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/gpattern.c b/glib/gpattern.c
index 16a0bf5f7..8725f509f 100644
--- a/glib/gpattern.c
+++ b/glib/gpattern.c
@@ -22,10 +22,11 @@
#include "gpattern.h"
#include "gmacros.h"
-#include "gmessages.h"
#include "gmem.h"
+#include "gmessages.h"
+#include "gstrfuncs.h"
#include "gunicode.h"
-#include "gutils.h"
+#include "gutils.h"
/**
* SECTION:patterns
@@ -157,7 +158,7 @@ g_pattern_ph_match (const gchar *match_pattern,
}
/**
- * g_pattern_match:
+ * g_pattern_spec_match:
* @pspec: a #GPatternSpec
* @string_length: the length of @string (in bytes, i.e. strlen(),
* not g_utf8_strlen())
@@ -183,12 +184,14 @@ g_pattern_ph_match (const gchar *match_pattern,
* g_utf8_strreverse() function to reverse UTF-8 encoded strings.
*
* Returns: %TRUE if @string matches @pspec
+ *
+ * Since: 2.70
**/
gboolean
-g_pattern_match (GPatternSpec *pspec,
- guint string_length,
- const gchar *string,
- const gchar *string_reversed)
+g_pattern_spec_match (GPatternSpec *pspec,
+ gsize string_length,
+ const gchar *string,
+ const gchar *string_reversed)
{
g_return_val_if_fail (pspec != NULL, FALSE);
g_return_val_if_fail (string != NULL, FALSE);
@@ -238,6 +241,44 @@ g_pattern_match (GPatternSpec *pspec,
}
/**
+ * g_pattern_match: (skip)
+ * @pspec: a #GPatternSpec
+ * @string_length: the length of @string (in bytes, i.e. strlen(),
+ * not g_utf8_strlen())
+ * @string: the UTF-8 encoded string to match
+ * @string_reversed: (nullable): the reverse of @string or %NULL
+ *
+ * Matches a string against a compiled pattern. Passing the correct
+ * length of the string given is mandatory. The reversed string can be
+ * omitted by passing %NULL, this is more efficient if the reversed
+ * version of the string to be matched is not at hand, as
+ * g_pattern_match() will only construct it if the compiled pattern
+ * requires reverse matches.
+ *
+ * Note that, if the user code will (possibly) match a string against a
+ * multitude of patterns containing wildcards, chances are high that
+ * some patterns will require a reversed string. In this case, it's
+ * more efficient to provide the reversed string to avoid multiple
+ * constructions thereof in the various calls to g_pattern_match().
+ *
+ * Note also that the reverse of a UTF-8 encoded string can in general
+ * not be obtained by g_strreverse(). This works only if the string
+ * does not contain any multibyte characters. GLib offers the
+ * g_utf8_strreverse() function to reverse UTF-8 encoded strings.
+ *
+ * Returns: %TRUE if @string matches @pspec
+ * Deprecated: 2.70: Use g_pattern_spec_match() instead
+ **/
+gboolean
+g_pattern_match (GPatternSpec *pspec,
+ guint string_length,
+ const gchar *string,
+ const gchar *string_reversed)
+{
+ return g_pattern_spec_match (pspec, string_length, string, string_reversed);
+}
+
+/**
* g_pattern_spec_new:
* @pattern: a zero-terminated UTF-8 encoded string
*
@@ -354,6 +395,30 @@ g_pattern_spec_new (const gchar *pattern)
}
/**
+ * g_pattern_spec_copy:
+ * @pspec: a #GPatternSpec
+ *
+ * Copies @pspec in a new #GPatternSpec.
+ *
+ * Returns: (transfer full): a copy of @pspec.
+ *
+ * Since: 2.70
+ **/
+GPatternSpec *
+g_pattern_spec_copy (GPatternSpec *pspec)
+{
+ GPatternSpec *pspec_copy;
+
+ g_return_val_if_fail (pspec != NULL, NULL);
+
+ pspec_copy = g_new (GPatternSpec, 1);
+ *pspec_copy = *pspec;
+ pspec_copy->pattern = g_strndup (pspec->pattern, pspec->pattern_length);
+
+ return pspec_copy;
+}
+
+/**
* g_pattern_spec_free:
* @pspec: a #GPatternSpec
*
@@ -391,7 +456,7 @@ g_pattern_spec_equal (GPatternSpec *pspec1,
}
/**
- * g_pattern_match_string:
+ * g_pattern_spec_match_string:
* @pspec: a #GPatternSpec
* @string: the UTF-8 encoded string to match
*
@@ -400,15 +465,36 @@ g_pattern_spec_equal (GPatternSpec *pspec1,
* g_pattern_match() instead while supplying the reversed string.
*
* Returns: %TRUE if @string matches @pspec
+ *
+ * Since: 2.70
**/
gboolean
-g_pattern_match_string (GPatternSpec *pspec,
- const gchar *string)
+g_pattern_spec_match_string (GPatternSpec *pspec,
+ const gchar *string)
{
g_return_val_if_fail (pspec != NULL, FALSE);
g_return_val_if_fail (string != NULL, FALSE);
- return g_pattern_match (pspec, strlen (string), string, NULL);
+ return g_pattern_spec_match (pspec, strlen (string), string, NULL);
+}
+
+/**
+ * g_pattern_match_string: (skip)
+ * @pspec: a #GPatternSpec
+ * @string: the UTF-8 encoded string to match
+ *
+ * Matches a string against a compiled pattern. If the string is to be
+ * matched against more than one pattern, consider using
+ * g_pattern_match() instead while supplying the reversed string.
+ *
+ * Returns: %TRUE if @string matches @pspec
+ * Deprecated: 2.70: Use g_pattern_spec_match_string() instead
+ **/
+gboolean
+g_pattern_match_string (GPatternSpec *pspec,
+ const gchar *string)
+{
+ return g_pattern_spec_match_string (pspec, string);
}
/**
@@ -434,7 +520,7 @@ g_pattern_match_simple (const gchar *pattern,
g_return_val_if_fail (string != NULL, FALSE);
pspec = g_pattern_spec_new (pattern);
- ergo = g_pattern_match (pspec, strlen (string), string, NULL);
+ ergo = g_pattern_spec_match (pspec, strlen (string), string, NULL);
g_pattern_spec_free (pspec);
return ergo;
diff --git a/glib/gpattern.h b/glib/gpattern.h
index bd9e4a7af..2d7f83077 100644
--- a/glib/gpattern.h
+++ b/glib/gpattern.h
@@ -33,15 +33,25 @@ GLIB_AVAILABLE_IN_ALL
GPatternSpec* g_pattern_spec_new (const gchar *pattern);
GLIB_AVAILABLE_IN_ALL
void g_pattern_spec_free (GPatternSpec *pspec);
+GLIB_AVAILABLE_IN_2_70
+GPatternSpec *g_pattern_spec_copy (GPatternSpec *pspec);
GLIB_AVAILABLE_IN_ALL
gboolean g_pattern_spec_equal (GPatternSpec *pspec1,
GPatternSpec *pspec2);
-GLIB_AVAILABLE_IN_ALL
+GLIB_AVAILABLE_IN_2_70
+gboolean g_pattern_spec_match (GPatternSpec *pspec,
+ gsize string_length,
+ const gchar *string,
+ const gchar *string_reversed);
+GLIB_AVAILABLE_IN_2_70
+gboolean g_pattern_spec_match_string (GPatternSpec *pspec,
+ const gchar *string);
+GLIB_DEPRECATED_IN_2_70_FOR (g_pattern_spec_match)
gboolean g_pattern_match (GPatternSpec *pspec,
guint string_length,
const gchar *string,
const gchar *string_reversed);
-GLIB_AVAILABLE_IN_ALL
+GLIB_DEPRECATED_IN_2_70_FOR (g_pattern_spec_match_string)
gboolean g_pattern_match_string (GPatternSpec *pspec,
const gchar *string);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/grcbox.h b/glib/grcbox.h
index 47dfd488b..0f8b99a80 100644
--- a/glib/grcbox.h
+++ b/glib/grcbox.h
@@ -23,11 +23,7 @@
#endif
#include <glib/gmem.h>
-
-#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
-/* for glib_typeof */
-#include <type_traits>
-#endif
+#include <glib/glib-typeof.h>
G_BEGIN_DECLS
@@ -76,7 +72,7 @@ gsize g_atomic_rc_box_get_size (gpointer mem_block);
#define g_atomic_rc_box_new0(type) \
((type *) g_atomic_rc_box_alloc0 (sizeof (type)))
-#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof)
/* Type check to avoid assigning references to different types */
#define g_rc_box_acquire(mem_block) \
((glib_typeof (mem_block)) (g_rc_box_acquire) (mem_block))
diff --git a/glib/grefcount.c b/glib/grefcount.c
index 7cb12fc46..6826a0005 100644
--- a/glib/grefcount.c
+++ b/glib/grefcount.c
@@ -84,7 +84,7 @@
* g_ref_count_init:
* @rc: the address of a reference count variable
*
- * Initializes a reference count variable.
+ * Initializes a reference count variable to 1.
*
* Since: 2.58
*/
@@ -142,6 +142,10 @@ void
*
* Decreases the reference count.
*
+ * If %TRUE is returned, the reference count reached 0. After this point, @rc
+ * is an undefined state and must be reinitialized with
+ * g_ref_count_init() to be used again.
+ *
* Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
*
* Since: 2.58
@@ -199,7 +203,7 @@ gboolean
* g_atomic_ref_count_init:
* @arc: the address of an atomic reference count variable
*
- * Initializes a reference count variable.
+ * Initializes a reference count variable to 1.
*
* Since: 2.58
*/
@@ -231,16 +235,14 @@ void
void
(g_atomic_ref_count_inc) (gatomicrefcount *arc)
{
- g_return_if_fail (arc != NULL);
- g_return_if_fail (g_atomic_int_get (arc) > 0);
+ gint old_value;
- if (g_atomic_int_get (arc) == G_MAXINT)
- {
- g_critical ("Reference count has reached saturation");
- return;
- }
+ g_return_if_fail (arc != NULL);
+ old_value = g_atomic_int_add (arc, 1);
+ g_return_if_fail (old_value > 0);
- g_atomic_int_inc (arc);
+ if (old_value == G_MAXINT)
+ g_critical ("Reference count has reached saturation");
}
/**
@@ -249,6 +251,10 @@ void
*
* Atomically decreases the reference count.
*
+ * If %TRUE is returned, the reference count reached 0. After this point, @arc
+ * is an undefined state and must be reinitialized with
+ * g_atomic_ref_count_init() to be used again.
+ *
* Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
*
* Since: 2.58
@@ -256,10 +262,13 @@ void
gboolean
(g_atomic_ref_count_dec) (gatomicrefcount *arc)
{
+ gint old_value;
+
g_return_val_if_fail (arc != NULL, FALSE);
- g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE);
+ old_value = g_atomic_int_add (arc, -1);
+ g_return_val_if_fail (old_value > 0, FALSE);
- return g_atomic_int_dec_and_test (arc);
+ return old_value == 1;
}
/**
diff --git a/glib/gregex.c b/glib/gregex.c
index 5e6ddfb46..a8a35a424 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -22,11 +22,7 @@
#include <string.h>
-#ifdef USE_SYSTEM_PCRE
#include <pcre.h>
-#else
-#include "pcre/pcre.h"
-#endif
#include "gtypes.h"
#include "gregex.h"
@@ -35,6 +31,7 @@
#include "gmessages.h"
#include "gstrfuncs.h"
#include "gatomic.h"
+#include "gtestutils.h"
#include "gthread.h"
/**
@@ -206,7 +203,8 @@ struct _GMatchInfo
gint ref_count; /* the ref count (atomic) */
GRegex *regex; /* the regex */
GRegexMatchFlags match_opts; /* options used at match time on the regex */
- gint matches; /* number of matching sub patterns */
+ gint matches; /* number of matching sub patterns, guaranteed to be <= (n_subpatterns + 1) if doing a single match (rather than matching all) */
+ gint n_subpatterns; /* total number of sub patterns in the regex */
gint pos; /* position in the string where last match left off */
gint n_offsets; /* number of offsets */
gint *offsets; /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
@@ -574,6 +572,9 @@ match_info_new (const GRegex *regex,
match_info->pos = start_position;
match_info->match_opts = match_options;
+ pcre_fullinfo (regex->pcre_re, regex->extra,
+ PCRE_INFO_CAPTURECOUNT, &match_info->n_subpatterns);
+
if (is_dfa)
{
/* These values should be enough for most cases, if they are not
@@ -584,10 +585,7 @@ match_info_new (const GRegex *regex,
}
else
{
- gint capture_count;
- pcre_fullinfo (regex->pcre_re, regex->extra,
- PCRE_INFO_CAPTURECOUNT, &capture_count);
- match_info->n_offsets = (capture_count + 1) * 3;
+ match_info->n_offsets = (match_info->n_subpatterns + 1) * 3;
}
match_info->offsets = g_new0 (gint, match_info->n_offsets);
@@ -768,6 +766,8 @@ g_match_info_next (GMatchInfo *match_info,
match_info->pos = match_info->offsets[1];
}
+ g_assert (match_info->matches <= match_info->n_subpatterns + 1);
+
/* it's possible to get two identical matches when we are matching
* empty strings, for instance if the pattern is "(?=[A-Z0-9])" and
* the string is "RegExTest" we have:
@@ -1044,16 +1044,21 @@ g_match_info_fetch_pos (const GMatchInfo *match_info,
g_return_val_if_fail (match_info != NULL, FALSE);
g_return_val_if_fail (match_num >= 0, FALSE);
+ /* check whether there was an error */
+ if (match_info->matches < 0)
+ return FALSE;
+
/* make sure the sub expression number they're requesting is less than
- * the total number of sub expressions that were matched. */
- if (match_num >= match_info->matches)
+ * the total number of sub expressions in the regex. When matching all
+ * (g_regex_match_all()), also compare against the number of matches */
+ if (match_num >= MAX (match_info->n_subpatterns + 1, match_info->matches))
return FALSE;
if (start_pos != NULL)
- *start_pos = match_info->offsets[2 * match_num];
+ *start_pos = (match_num < match_info->matches) ? match_info->offsets[2 * match_num] : -1;
if (end_pos != NULL)
- *end_pos = match_info->offsets[2 * match_num + 1];
+ *end_pos = (match_num < match_info->matches) ? match_info->offsets[2 * match_num + 1] : -1;
return TRUE;
}
@@ -1989,6 +1994,9 @@ g_regex_match_all_full (const GRegex *regex,
pcre_free (pcre_re);
#endif
+ /* don’t assert that (info->matches <= info->n_subpatterns + 1) as that only
+ * holds true for a single match, rather than matching all */
+
/* set info->pos to -1 so that a call to g_match_info_next() fails. */
info->pos = -1;
retval = info->matches >= 0;
diff --git a/glib/gscanner.c b/glib/gscanner.c
index c858abf9e..9102b3a92 100644
--- a/glib/gscanner.c
+++ b/glib/gscanner.c
@@ -1678,7 +1678,7 @@ g_scanner_get_token_i (GScanner *scanner,
case G_TOKEN_SYMBOL:
if (scanner->config->symbol_2_token)
- *token_p = (GTokenType) value_p->v_symbol;
+ *token_p = (GTokenType) ((size_t) value_p->v_symbol);
break;
case G_TOKEN_BINARY:
diff --git a/glib/gspawn-win32.c b/glib/gspawn-win32.c
index 0f6579eab..638bac5cd 100644
--- a/glib/gspawn-win32.c
+++ b/glib/gspawn-win32.c
@@ -531,6 +531,28 @@ do_spawn_directly (gint *exit_status,
}
static gboolean
+might_be_console_process (void)
+{
+ // we should always fail to attach ourself to a console (because we're
+ // either already attached, or we do not have a console)
+ gboolean attached_to_self = AttachConsole (GetCurrentProcessId ());
+ g_return_val_if_fail (!attached_to_self, TRUE);
+
+ switch (GetLastError ())
+ {
+ // current process is already attached to a console
+ case ERROR_ACCESS_DENIED:
+ return TRUE;
+ // current process does not have a console
+ case ERROR_INVALID_HANDLE:
+ return FALSE;
+ // we should not get ERROR_INVALID_PARAMETER
+ }
+
+ g_return_val_if_reached (FALSE);
+}
+
+static gboolean
fork_exec (gint *exit_status,
gboolean do_return_handle,
const gchar *working_directory,
@@ -625,7 +647,7 @@ fork_exec (gint *exit_status,
goto cleanup_and_fail;
new_argv = g_new (char *, argc + 1 + ARG_COUNT);
- if (GetConsoleWindow () != NULL)
+ if (might_be_console_process ())
helper_process = HELPER_PROCESS "-console.exe";
else
helper_process = HELPER_PROCESS ".exe";
@@ -927,7 +949,7 @@ g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
gint outpipe = -1;
@@ -1102,8 +1124,8 @@ g_spawn_sync (const gchar *working_directory,
/* No helper process, exit status of actual spawned process
* already available.
*/
- if (exit_status)
- *exit_status = status;
+ if (wait_status)
+ *wait_status = status;
}
else
{
@@ -1119,8 +1141,8 @@ g_spawn_sync (const gchar *working_directory,
switch (helper_report[0])
{
case CHILD_NO_ERROR:
- if (exit_status)
- *exit_status = helper_report[1];
+ if (wait_status)
+ *wait_status = helper_report[1];
break;
default:
set_child_error (helper_report, working_directory, error);
@@ -1310,7 +1332,7 @@ gboolean
g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
gboolean retval;
@@ -1331,7 +1353,7 @@ g_spawn_command_line_sync (const gchar *command_line,
NULL,
standard_output,
standard_error,
- exit_status,
+ wait_status,
error);
g_strfreev (argv);
@@ -1372,16 +1394,18 @@ g_spawn_close_pid (GPid pid)
}
gboolean
-g_spawn_check_exit_status (gint exit_status,
+g_spawn_check_wait_status (gint wait_status,
GError **error)
{
gboolean ret = FALSE;
- if (exit_status != 0)
+ if (wait_status != 0)
{
- g_set_error (error, G_SPAWN_EXIT_ERROR, exit_status,
+ /* On Windows, the wait status is just the exit status: the
+ * difference between the two that exists on Unix is not relevant */
+ g_set_error (error, G_SPAWN_EXIT_ERROR, wait_status,
_("Child process exited with code %ld"),
- (long) exit_status);
+ (long) wait_status);
goto out;
}
@@ -1390,6 +1414,13 @@ g_spawn_check_exit_status (gint exit_status,
return ret;
}
+gboolean
+g_spawn_check_exit_status (gint wait_status,
+ GError **error)
+{
+ return g_spawn_check_wait_status (wait_status, error);
+}
+
#ifdef G_OS_WIN32
/* Binary compatibility versions. Not for newly compiled code. */
@@ -1421,12 +1452,12 @@ _GLIB_EXTERN gboolean g_spawn_sync_utf8 (const gchar *wo
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error);
_GLIB_EXTERN gboolean g_spawn_command_line_sync_utf8 (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error);
_GLIB_EXTERN gboolean g_spawn_command_line_async_utf8 (const gchar *command_line,
GError **error);
@@ -1486,7 +1517,7 @@ g_spawn_sync_utf8 (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
return g_spawn_sync (working_directory,
@@ -1497,7 +1528,7 @@ g_spawn_sync_utf8 (const gchar *working_directory,
user_data,
standard_output,
standard_error,
- exit_status,
+ wait_status,
error);
}
@@ -1505,13 +1536,13 @@ gboolean
g_spawn_command_line_sync_utf8 (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
return g_spawn_command_line_sync (command_line,
standard_output,
standard_error,
- exit_status,
+ wait_status,
error);
}
diff --git a/glib/gspawn.c b/glib/gspawn.c
index a15fb1ca1..899647c2f 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -141,7 +141,7 @@ extern char **environ;
* gpointer user_data)
* {
* g_message ("Child %" G_PID_FORMAT " exited %s", pid,
- * g_spawn_check_exit_status (status, NULL) ? "normally" : "abnormally");
+ * g_spawn_check_wait_status (status, NULL) ? "normally" : "abnormally");
*
* // Free any resources associated with the child here, such as I/O channels
* // on its stdout and stderr FDs. If you have no code to put in the
@@ -249,16 +249,6 @@ g_spawn_async (const gchar *working_directory,
error);
}
-/* This function is called between fork() and exec() and hence must be
- * async-signal-safe (see signal-safety(7)). */
-static gint
-steal_fd (gint *fd)
-{
- gint fd_out = *fd;
- *fd = -1;
- return fd_out;
-}
-
/* Avoids a danger in threaded situations (calling close()
* on a file descriptor twice, and another thread has
* re-opened it since the first close)
@@ -335,7 +325,7 @@ read_data (GString *str,
* @user_data: (closure): user data for @child_setup
* @standard_output: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child output, or %NULL
* @standard_error: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child error messages, or %NULL
- * @exit_status: (out) (optional): return location for child exit status, as returned by waitpid(), or %NULL
+ * @wait_status: (out) (optional): return location for child wait status, as returned by waitpid(), or %NULL
* @error: return location for error, or %NULL
*
* Executes a child synchronously (waits for the child to exit before returning).
@@ -344,15 +334,18 @@ read_data (GString *str,
* %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when
* passing %NULL for @standard_output and @standard_error.
*
- * If @exit_status is non-%NULL, the platform-specific exit status of
+ * If @wait_status is non-%NULL, the platform-specific status of
* the child is stored there; see the documentation of
- * g_spawn_check_exit_status() for how to use and interpret this.
+ * g_spawn_check_wait_status() for how to use and interpret this.
+ * On Unix platforms, note that it is usually not equal
+ * to the integer passed to `exit()` or returned from `main()`.
+ *
* Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in
* @flags, and on POSIX platforms, the same restrictions as for
* g_child_watch_source_new() apply.
*
* If an error occurs, no data is returned in @standard_output,
- * @standard_error, or @exit_status.
+ * @standard_error, or @wait_status.
*
* This function calls g_spawn_async_with_pipes() internally; see that
* function for full details on the other parameters and details on
@@ -369,7 +362,7 @@ g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
gint outpipe = -1;
@@ -527,13 +520,13 @@ g_spawn_sync (const gchar *working_directory,
goto again;
else if (errno == ECHILD)
{
- if (exit_status)
+ if (wait_status)
{
- g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes.");
+ g_warning ("In call to g_spawn_sync(), wait status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes.");
}
else
{
- /* We don't need the exit status. */
+ /* We don't need the wait status. */
}
}
else
@@ -564,8 +557,8 @@ g_spawn_sync (const gchar *working_directory,
}
else
{
- if (exit_status)
- *exit_status = status;
+ if (wait_status)
+ *wait_status = status;
if (standard_output)
*standard_output = g_string_free (outstr, FALSE);
@@ -989,7 +982,7 @@ g_spawn_async_with_fds (const gchar *working_directory,
* @command_line: (type filename): a command line
* @standard_output: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child output
* @standard_error: (out) (array zero-terminated=1) (element-type guint8) (optional): return location for child errors
- * @exit_status: (out) (optional): return location for child exit status, as returned by waitpid()
+ * @wait_status: (out) (optional): return location for child wait status, as returned by waitpid()
* @error: return location for errors
*
* A simple version of g_spawn_sync() with little-used parameters
@@ -1001,9 +994,11 @@ g_spawn_async_with_fds (const gchar *working_directory,
* appropriate. Possible errors are those from g_spawn_sync() and those
* from g_shell_parse_argv().
*
- * If @exit_status is non-%NULL, the platform-specific exit status of
+ * If @wait_status is non-%NULL, the platform-specific status of
* the child is stored there; see the documentation of
- * g_spawn_check_exit_status() for how to use and interpret this.
+ * g_spawn_check_wait_status() for how to use and interpret this.
+ * On Unix platforms, note that it is usually not equal
+ * to the integer passed to `exit()` or returned from `main()`.
*
* On Windows, please note the implications of g_shell_parse_argv()
* parsing @command_line. Parsing is done according to Unix shell rules, not
@@ -1021,7 +1016,7 @@ gboolean
g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error)
{
gboolean retval;
@@ -1042,7 +1037,7 @@ g_spawn_command_line_sync (const gchar *command_line,
NULL,
standard_output,
standard_error,
- exit_status,
+ wait_status,
error);
g_strfreev (argv);
@@ -1094,80 +1089,83 @@ g_spawn_command_line_async (const gchar *command_line,
}
/**
- * g_spawn_check_exit_status:
- * @exit_status: An exit code as returned from g_spawn_sync()
+ * g_spawn_check_wait_status:
+ * @wait_status: A platform-specific wait status as returned from g_spawn_sync()
* @error: a #GError
*
- * Set @error if @exit_status indicates the child exited abnormally
+ * Set @error if @wait_status indicates the child exited abnormally
* (e.g. with a nonzero exit code, or via a fatal signal).
*
- * The g_spawn_sync() and g_child_watch_add() family of APIs return an
- * exit status for subprocesses encoded in a platform-specific way.
+ * The g_spawn_sync() and g_child_watch_add() family of APIs return the
+ * status of subprocesses encoded in a platform-specific way.
* On Unix, this is guaranteed to be in the same format waitpid() returns,
* and on Windows it is guaranteed to be the result of GetExitCodeProcess().
*
* Prior to the introduction of this function in GLib 2.34, interpreting
- * @exit_status required use of platform-specific APIs, which is problematic
+ * @wait_status required use of platform-specific APIs, which is problematic
* for software using GLib as a cross-platform layer.
*
* Additionally, many programs simply want to determine whether or not
* the child exited successfully, and either propagate a #GError or
* print a message to standard error. In that common case, this function
* can be used. Note that the error message in @error will contain
- * human-readable information about the exit status.
+ * human-readable information about the wait status.
*
* The @domain and @code of @error have special semantics in the case
* where the process has an "exit code", as opposed to being killed by
* a signal. On Unix, this happens if WIFEXITED() would be true of
- * @exit_status. On Windows, it is always the case.
+ * @wait_status. On Windows, it is always the case.
*
* The special semantics are that the actual exit code will be the
* code set in @error, and the domain will be %G_SPAWN_EXIT_ERROR.
* This allows you to differentiate between different exit codes.
*
* If the process was terminated by some means other than an exit
- * status, the domain will be %G_SPAWN_ERROR, and the code will be
- * %G_SPAWN_ERROR_FAILED.
+ * status (for example if it was killed by a signal), the domain will be
+ * %G_SPAWN_ERROR and the code will be %G_SPAWN_ERROR_FAILED.
*
* This function just offers convenience; you can of course also check
* the available platform via a macro such as %G_OS_UNIX, and use
- * WIFEXITED() and WEXITSTATUS() on @exit_status directly. Do not attempt
+ * WIFEXITED() and WEXITSTATUS() on @wait_status directly. Do not attempt
* to scan or parse the error message string; it may be translated and/or
* change in future versions of GLib.
*
+ * Prior to version 2.70, g_spawn_check_exit_status() provides the same
+ * functionality, although under a misleading name.
+ *
* Returns: %TRUE if child exited successfully, %FALSE otherwise (and
* @error will be set)
*
- * Since: 2.34
+ * Since: 2.70
*/
gboolean
-g_spawn_check_exit_status (gint exit_status,
+g_spawn_check_wait_status (gint wait_status,
GError **error)
{
gboolean ret = FALSE;
- if (WIFEXITED (exit_status))
+ if (WIFEXITED (wait_status))
{
- if (WEXITSTATUS (exit_status) != 0)
+ if (WEXITSTATUS (wait_status) != 0)
{
- g_set_error (error, G_SPAWN_EXIT_ERROR, WEXITSTATUS (exit_status),
+ g_set_error (error, G_SPAWN_EXIT_ERROR, WEXITSTATUS (wait_status),
_("Child process exited with code %ld"),
- (long) WEXITSTATUS (exit_status));
+ (long) WEXITSTATUS (wait_status));
goto out;
}
}
- else if (WIFSIGNALED (exit_status))
+ else if (WIFSIGNALED (wait_status))
{
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
_("Child process killed by signal %ld"),
- (long) WTERMSIG (exit_status));
+ (long) WTERMSIG (wait_status));
goto out;
}
- else if (WIFSTOPPED (exit_status))
+ else if (WIFSTOPPED (wait_status))
{
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
_("Child process stopped by signal %ld"),
- (long) WSTOPSIG (exit_status));
+ (long) WSTOPSIG (wait_status));
goto out;
}
else
@@ -1182,6 +1180,34 @@ g_spawn_check_exit_status (gint exit_status,
return ret;
}
+/**
+ * g_spawn_check_exit_status:
+ * @wait_status: A status as returned from g_spawn_sync()
+ * @error: a #GError
+ *
+ * An old name for g_spawn_check_wait_status(), deprecated because its
+ * name is misleading.
+ *
+ * Despite the name of the function, @wait_status must be the wait status
+ * as returned by g_spawn_sync(), g_subprocess_get_status(), `waitpid()`,
+ * etc. On Unix platforms, it is incorrect for it to be the exit status
+ * as passed to `exit()` or returned by g_subprocess_get_exit_status() or
+ * `WEXITSTATUS()`.
+ *
+ * Returns: %TRUE if child exited successfully, %FALSE otherwise (and
+ * @error will be set)
+ *
+ * Since: 2.34
+ *
+ * Deprecated: 2.70: Use g_spawn_check_wait_status() instead, and check whether your code is conflating wait and exit statuses.
+ */
+gboolean
+g_spawn_check_exit_status (gint wait_status,
+ GError **error)
+{
+ return g_spawn_check_wait_status (wait_status, error);
+}
+
/* This function is called between fork() and exec() and hence must be
* async-signal-safe (see signal-safety(7)). */
static gssize
@@ -1494,7 +1520,7 @@ safe_closefrom (int lowfd)
*
* Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
* fall back to safe_fdwalk(). */
- if (close_range (lowfd, G_MAXUINT, 0) != 0 && errno == ENOSYS)
+ if (close_range (lowfd, G_MAXUINT) != 0 && errno == ENOSYS)
#endif /* HAVE_CLOSE_RANGE */
(void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd));
#endif
@@ -2436,13 +2462,13 @@ success:
close_and_invalidate (&stderr_pipe[1]);
if (stdin_pipe_out != NULL)
- *stdin_pipe_out = steal_fd (&stdin_pipe[1]);
+ *stdin_pipe_out = g_steal_fd (&stdin_pipe[1]);
if (stdout_pipe_out != NULL)
- *stdout_pipe_out = steal_fd (&stdout_pipe[0]);
+ *stdout_pipe_out = g_steal_fd (&stdout_pipe[0]);
if (stderr_pipe_out != NULL)
- *stderr_pipe_out = steal_fd (&stderr_pipe[0]);
+ *stderr_pipe_out = g_steal_fd (&stderr_pipe[0]);
return TRUE;
diff --git a/glib/gspawn.h b/glib/gspawn.h
index e09dc2aec..3cad30765 100644
--- a/glib/gspawn.h
+++ b/glib/gspawn.h
@@ -95,7 +95,7 @@ typedef enum
/**
* G_SPAWN_EXIT_ERROR:
*
- * Error domain used by g_spawn_check_exit_status(). The code
+ * Error domain used by g_spawn_check_wait_status(). The code
* will be the program exit code.
*/
#define G_SPAWN_EXIT_ERROR g_spawn_exit_error_quark ()
@@ -259,21 +259,25 @@ gboolean g_spawn_sync (const gchar *working_directory,
gpointer user_data,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL
gboolean g_spawn_command_line_sync (const gchar *command_line,
gchar **standard_output,
gchar **standard_error,
- gint *exit_status,
+ gint *wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL
gboolean g_spawn_command_line_async (const gchar *command_line,
GError **error);
-GLIB_AVAILABLE_IN_2_34
-gboolean g_spawn_check_exit_status (gint exit_status,
+GLIB_AVAILABLE_IN_2_70
+gboolean g_spawn_check_wait_status (gint wait_status,
+ GError **error);
+
+GLIB_DEPRECATED_IN_2_70_FOR(g_spawn_check_wait_status)
+gboolean g_spawn_check_exit_status (gint wait_status,
GError **error);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/gstring.c b/glib/gstring.c
index 4f1d116d3..ad2ec1771 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -963,13 +963,8 @@ g_string_erase (GString *string,
*
* Replaces the string @find with the string @replace in a #GString up to
* @limit times. If the number of instances of @find in the #GString is
- * less than @limit, all instances are replaced. If the number of
- * instances is `0`, all instances of @find are replaced.
- *
- * If @find is the empty string, since versions 2.69.1 and 2.68.4 the
- * replacement will be inserted no more than once per possible position
- * (beginning of string, end of string and between characters). This did
- * not work correctly in earlier versions.
+ * less than @limit, all instances are replaced. If @limit is `0`,
+ * all instances of @find are replaced.
*
* Returns: the number of find and replace operations performed.
*
@@ -983,7 +978,7 @@ g_string_replace (GString *string,
{
gsize f_len, r_len, pos;
gchar *cur, *next;
- gint n = 0;
+ guint n = 0;
g_return_val_if_fail (string != NULL, 0);
g_return_val_if_fail (find != NULL, 0);
@@ -1000,15 +995,6 @@ g_string_replace (GString *string,
g_string_insert (string, pos, replace);
cur = string->str + pos + r_len;
n++;
- /* Only match the empty string once at any given position, to
- * avoid infinite loops */
- if (f_len == 0)
- {
- if (cur[0] == '\0')
- break;
- else
- cur++;
- }
if (n == limit)
break;
}
diff --git a/glib/gstrvbuilder.c b/glib/gstrvbuilder.c
index 909360c95..07030b92f 100644
--- a/glib/gstrvbuilder.c
+++ b/glib/gstrvbuilder.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2020 Canonical Ltd.
+ * Copyright © 2021 Alexandros Theodotou
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +22,7 @@
#include "garray.h"
#include "gmem.h"
+#include "gmessages.h"
/**
* SECTION:gstrvbuilder
@@ -114,6 +116,48 @@ g_strv_builder_add (GStrvBuilder *builder,
}
/**
+ * g_strv_builder_addv:
+ * @builder: a #GStrvBuilder
+ * @value: (array zero-terminated=1): the vector of strings to add
+ *
+ * Appends all the strings in the given vector to the builder.
+ *
+ * Since 2.70
+ */
+void
+g_strv_builder_addv (GStrvBuilder *builder,
+ const char **value)
+{
+ gsize i = 0;
+ g_return_if_fail (builder != NULL);
+ g_return_if_fail (value != NULL);
+ for (i = 0; value[i] != NULL; i++)
+ g_strv_builder_add (builder, value[i]);
+}
+
+/**
+ * g_strv_builder_add_many:
+ * @builder: a #GStrvBuilder
+ * @...: one or more strings followed by %NULL
+ *
+ * Appends all the given strings to the builder.
+ *
+ * Since 2.70
+ */
+void
+g_strv_builder_add_many (GStrvBuilder *builder,
+ ...)
+{
+ va_list var_args;
+ const gchar *str;
+ g_return_if_fail (builder != NULL);
+ va_start (var_args, builder);
+ while ((str = va_arg (var_args, gchar *)) != NULL)
+ g_strv_builder_add (builder, str);
+ va_end (var_args);
+}
+
+/**
* g_strv_builder_end:
* @builder: a #GStrvBuilder
*
diff --git a/glib/gstrvbuilder.h b/glib/gstrvbuilder.h
index 395bcfbbe..48aee0128 100644
--- a/glib/gstrvbuilder.h
+++ b/glib/gstrvbuilder.h
@@ -1,5 +1,6 @@
/*
* Copyright © 2020 Canonical Ltd.
+ * Copyright © 2021 Alexandros Theodotou
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,7 +30,7 @@ G_BEGIN_DECLS
/**
* GStrvBuilder:
- *
+ *
* A helper object to build a %NULL-terminated string array
* by appending. See g_strv_builder_new().
*
@@ -50,6 +51,14 @@ GLIB_AVAILABLE_IN_2_68
void g_strv_builder_add (GStrvBuilder *builder,
const char *value);
+GLIB_AVAILABLE_IN_2_70
+void g_strv_builder_addv (GStrvBuilder *builder,
+ const char **value);
+
+GLIB_AVAILABLE_IN_2_70
+void g_strv_builder_add_many (GStrvBuilder *builder,
+ ...) G_GNUC_NULL_TERMINATED;
+
GLIB_AVAILABLE_IN_2_68
GStrv g_strv_builder_end (GStrvBuilder *builder);
diff --git a/glib/gtester.c b/glib/gtester.c
index fdcdaca10..94cfba641 100644
--- a/glib/gtester.c
+++ b/glib/gtester.c
@@ -745,6 +745,7 @@ fixture_test (guint *fix,
g_test_bug ("123");
g_test_bug_base ("http://www.example.com/bugtracker?bugnum=%s;cmd=showbug");
g_test_bug ("456");
+ g_test_bug ("https://example.com/no-base-used");
}
static void
fixture_teardown (guint *fix,
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index d9a04e044..2c3ea24a8 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -2013,7 +2013,7 @@ g_test_message (const char *format,
* case only.
* Bug URIs are constructed by appending a bug specific URI
* portion to @uri_pattern, or by replacing the special string
- * '\%s' within @uri_pattern if that is present.
+ * `%s` within @uri_pattern if that is present.
*
* If g_test_bug_base() is not called, bug URIs are formed solely
* from the value provided by g_test_bug().
@@ -2029,15 +2029,19 @@ g_test_bug_base (const char *uri_pattern)
/**
* g_test_bug:
- * @bug_uri_snippet: Bug specific bug tracker URI portion.
+ * @bug_uri_snippet: Bug specific bug tracker URI or URI portion.
*
* This function adds a message to test reports that
* associates a bug URI with a test case.
+ *
* Bug URIs are constructed from a base URI set with g_test_bug_base()
* and @bug_uri_snippet. If g_test_bug_base() has not been called, it is
* assumed to be the empty string, so a full URI can be provided to
* g_test_bug() instead.
*
+ * Since GLib 2.70, the base URI is not prepended to @bug_uri_snippet if it
+ * is already a valid URI.
+ *
* Since: 2.16
* See also: g_test_summary()
*/
@@ -2048,6 +2052,13 @@ g_test_bug (const char *bug_uri_snippet)
g_return_if_fail (bug_uri_snippet != NULL);
+ if (g_str_has_prefix (bug_uri_snippet, "http:") ||
+ g_str_has_prefix (bug_uri_snippet, "https:"))
+ {
+ g_test_message ("Bug Reference: %s", bug_uri_snippet);
+ return;
+ }
+
if (test_uri_base != NULL)
c = strstr (test_uri_base, "%s");
if (c)
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index 305152ae7..15d5d4e52 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -559,6 +559,38 @@ g_thread_pool_new (GFunc func,
gboolean exclusive,
GError **error)
{
+ return g_thread_pool_new_full (func, user_data, NULL, max_threads, exclusive, error);
+}
+
+/**
+ * g_thread_pool_new_full:
+ * @func: a function to execute in the threads of the new thread pool
+ * @user_data: user data that is handed over to @func every time it
+ * is called
+ * @item_free_func: (nullable): used to pass as a free function to
+ * g_async_queue_new_full()
+ * @max_threads: the maximal number of threads to execute concurrently
+ * in the new thread pool, `-1` means no limit
+ * @exclusive: should this thread pool be exclusive?
+ * @error: return location for error, or %NULL
+ *
+ * This function creates a new thread pool similar to g_thread_pool_new()
+ * but allowing @item_free_func to be specified to free the data passed
+ * to g_thread_pool_push() in the case that the #GThreadPool is stopped
+ * and freed before all tasks have been executed.
+ *
+ * Returns: (transfer full): the new #GThreadPool
+ *
+ * Since: 2.70
+ */
+GThreadPool *
+g_thread_pool_new_full (GFunc func,
+ gpointer user_data,
+ GDestroyNotify item_free_func,
+ gint max_threads,
+ gboolean exclusive,
+ GError **error)
+{
GRealThreadPool *retval;
G_LOCK_DEFINE_STATIC (init);
@@ -571,7 +603,7 @@ g_thread_pool_new (GFunc func,
retval->pool.func = func;
retval->pool.user_data = user_data;
retval->pool.exclusive = exclusive;
- retval->queue = g_async_queue_new ();
+ retval->queue = g_async_queue_new_full (item_free_func);
g_cond_init (&retval->cond);
retval->max_threads = max_threads;
retval->num_threads = 0;
diff --git a/glib/gthreadpool.h b/glib/gthreadpool.h
index 11c3d1d16..f2501b88b 100644
--- a/glib/gthreadpool.h
+++ b/glib/gthreadpool.h
@@ -51,6 +51,13 @@ GThreadPool * g_thread_pool_new (GFunc func,
gint max_threads,
gboolean exclusive,
GError **error);
+GLIB_AVAILABLE_IN_2_70
+GThreadPool * g_thread_pool_new_full (GFunc func,
+ gpointer user_data,
+ GDestroyNotify item_free_func,
+ gint max_threads,
+ gboolean exclusive,
+ GError **error);
GLIB_AVAILABLE_IN_ALL
void g_thread_pool_free (GThreadPool *pool,
gboolean immediate,
diff --git a/glib/gtree.c b/glib/gtree.c
index 94842ac92..6ed917514 100644
--- a/glib/gtree.c
+++ b/glib/gtree.c
@@ -338,7 +338,16 @@ g_tree_node_next (GTreeNode *node)
return tmp;
}
-static void
+/**
+ * g_tree_remove_all:
+ * @tree: a #GTree
+ *
+ * Removes all nodes from a #GTree and destroys their keys and values,
+ * then resets the #GTree’s root to %NULL.
+ *
+ * Since: 2.70
+ */
+void
g_tree_remove_all (GTree *tree)
{
GTreeNode *node;
diff --git a/glib/gtree.h b/glib/gtree.h
index 19f9f7ea1..ff11ba435 100644
--- a/glib/gtree.h
+++ b/glib/gtree.h
@@ -111,6 +111,10 @@ void g_tree_replace (GTree *tree,
GLIB_AVAILABLE_IN_ALL
gboolean g_tree_remove (GTree *tree,
gconstpointer key);
+
+GLIB_AVAILABLE_IN_2_70
+void g_tree_remove_all (GTree *tree);
+
GLIB_AVAILABLE_IN_ALL
gboolean g_tree_steal (GTree *tree,
gconstpointer key);
diff --git a/glib/gunicollate.c b/glib/gunicollate.c
index d54ef19ed..dfed1041d 100644
--- a/glib/gunicollate.c
+++ b/glib/gunicollate.c
@@ -441,7 +441,7 @@ g_utf8_collate_key (const gchar *str,
if (str_locale)
{
xfrm_len = strxfrm (NULL, str_locale, 0);
- if (xfrm_len < 0 || xfrm_len >= G_MAXINT - 2)
+ if (xfrm_len >= G_MAXINT - 2)
{
g_free (str_locale);
str_locale = NULL;
diff --git a/glib/guri.c b/glib/guri.c
index a57c670ac..2c94efbc6 100644
--- a/glib/guri.c
+++ b/glib/guri.c
@@ -1508,6 +1508,10 @@ g_uri_parse_relative (GUri *base_uri,
uri->port = normalize_port (uri->scheme, uri->port);
}
}
+ else
+ {
+ remove_dot_segments (uri->path);
+ }
return g_steal_pointer (&uri);
}
diff --git a/glib/gutf8.c b/glib/gutf8.c
index 51ad0d09b..ca1a395c1 100644
--- a/glib/gutf8.c
+++ b/glib/gutf8.c
@@ -706,7 +706,7 @@ g_utf8_get_char_validated (const gchar *p,
* @str: a UTF-8 encoded string
* @len: the maximum length of @str to use, in bytes. If @len < 0,
* then the string is nul-terminated.
- * @items_written: (out caller-allocates) (optional): location to store the
+ * @items_written: (out) (optional): location to store the
* number of characters in the result, or %NULL.
*
* Convert a string from UTF-8 to a 32-bit fixed width
@@ -823,13 +823,13 @@ try_malloc_n (gsize n_blocks, gsize n_block_bytes, GError **error)
* @str: a UTF-8 encoded string
* @len: the maximum length of @str to use, in bytes. If @len < 0,
* then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* bytes read, or %NULL.
* If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be
* returned in case @str contains a trailing partial
* character. If an error occurs then the index of the
* invalid input is stored here.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of characters written or %NULL. The value here stored does not include
* the trailing 0 character.
* @error: location to store the error occurring, or %NULL to ignore
@@ -909,9 +909,9 @@ g_utf8_to_ucs4 (const gchar *str,
* @str: a UCS-4 encoded string
* @len: the maximum length (number of characters) of @str to use.
* If @len < 0, then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* characters read, or %NULL.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of bytes written or %NULL. The value here stored does not include the
* trailing 0 byte.
* @error: location to store the error occurring, or %NULL to ignore
@@ -983,11 +983,11 @@ g_ucs4_to_utf8 (const gunichar *str,
* @str: a UTF-16 encoded string
* @len: the maximum length (number of #gunichar2) of @str to use.
* If @len < 0, then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* words read, or %NULL. If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will
* be returned in case @str contains a trailing partial character. If
* an error occurs then the index of the invalid input is stored here.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of bytes written, or %NULL. The value stored here does not include the
* trailing 0 byte.
* @error: location to store the error occurring, or %NULL to ignore
@@ -1138,11 +1138,11 @@ g_utf16_to_utf8 (const gunichar2 *str,
* @str: a UTF-16 encoded string
* @len: the maximum length (number of #gunichar2) of @str to use.
* If @len < 0, then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* words read, or %NULL. If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will
* be returned in case @str contains a trailing partial character. If
* an error occurs then the index of the invalid input is stored here.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of characters written, or %NULL. The value stored here does not include
* the trailing 0 character.
* @error: location to store the error occurring, or %NULL to ignore
@@ -1276,11 +1276,11 @@ g_utf16_to_ucs4 (const gunichar2 *str,
* @str: a UTF-8 encoded string
* @len: the maximum length (number of bytes) of @str to use.
* If @len < 0, then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* bytes read, or %NULL. If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will
* be returned in case @str contains a trailing partial character. If
* an error occurs then the index of the invalid input is stored here.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of #gunichar2 written, or %NULL. The value stored here does not include
* the trailing 0.
* @error: location to store the error occurring, or %NULL to ignore
@@ -1393,10 +1393,10 @@ g_utf8_to_utf16 (const gchar *str,
* @str: a UCS-4 encoded string
* @len: the maximum length (number of characters) of @str to use.
* If @len < 0, then the string is nul-terminated.
- * @items_read: (out caller-allocates) (optional): location to store number of
+ * @items_read: (out) (optional): location to store number of
* bytes read, or %NULL. If an error occurs then the index of the invalid
* input is stored here.
- * @items_written: (out caller-allocates) (optional): location to store number
+ * @items_written: (out) (optional): location to store number
* of #gunichar2 written, or %NULL. The value stored here does not include
* the trailing 0.
* @error: location to store the error occurring, or %NULL to ignore
diff --git a/glib/gutils.c b/glib/gutils.c
index dad162528..b7a2113d4 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -340,7 +340,17 @@ g_find_program_in_path (const gchar *program)
{
if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
!g_file_test (program, G_FILE_TEST_IS_DIR))
- return g_strdup (program);
+ {
+ gchar *out = NULL, *cwd = NULL;
+
+ if (g_path_is_absolute (program))
+ return g_strdup (program);
+
+ cwd = g_get_current_dir ();
+ out = g_build_filename (cwd, program, NULL);
+ g_free (cwd);
+ return g_steal_pointer (&out);
+ }
else
return NULL;
}
@@ -548,23 +558,20 @@ static gchar **g_user_special_dirs = NULL;
#ifdef G_OS_WIN32
static gchar *
-get_special_folder (int csidl)
+get_special_folder (REFKNOWNFOLDERID known_folder_guid_ptr)
{
- wchar_t path[MAX_PATH+1];
+ wchar_t *wcp = NULL;
+ gchar *result = NULL;
HRESULT hr;
- LPITEMIDLIST pidl = NULL;
- BOOL b;
- gchar *retval = NULL;
- hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
- if (hr == S_OK)
- {
- b = SHGetPathFromIDListW (pidl, path);
- if (b)
- retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
- CoTaskMemFree (pidl);
- }
- return retval;
+ hr = SHGetKnownFolderPath (known_folder_guid_ptr, 0, NULL, &wcp);
+
+ if (SUCCEEDED (hr))
+ result = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
+
+ CoTaskMemFree (wcp);
+
+ return result;
}
static char *
@@ -814,7 +821,7 @@ g_build_home_dir (void)
}
if (home_dir == NULL)
- home_dir = get_special_folder (CSIDL_PROFILE);
+ home_dir = get_special_folder (&FOLDERID_Profile);
if (home_dir == NULL)
home_dir = get_windows_directory_root ();
@@ -1704,7 +1711,7 @@ g_build_user_data_dir (void)
data_dir = g_strdup (data_dir_env);
#ifdef G_OS_WIN32
else
- data_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
+ data_dir = get_special_folder (&FOLDERID_LocalAppData);
#endif
if (!data_dir || !data_dir[0])
{
@@ -1730,7 +1737,7 @@ g_build_user_data_dir (void)
* On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
* is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
* opposed to roaming) application data is used instead. See the
- * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
+ * [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
* Note that in this case on Windows it will be the same
* as what g_get_user_config_dir() returns.
*
@@ -1768,7 +1775,7 @@ g_build_user_config_dir (void)
config_dir = g_strdup (config_dir_env);
#ifdef G_OS_WIN32
else
- config_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
+ config_dir = get_special_folder (&FOLDERID_LocalAppData);
#endif
if (!config_dir || !config_dir[0])
{
@@ -1794,7 +1801,7 @@ g_build_user_config_dir (void)
* On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
* If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
* to roaming) application data is used instead. See the
- * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
+ * [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
* Note that in this case on Windows it will be the same
* as what g_get_user_data_dir() returns.
*
@@ -1831,7 +1838,7 @@ g_build_user_cache_dir (void)
cache_dir = g_strdup (cache_dir_env);
#ifdef G_OS_WIN32
else
- cache_dir = get_special_folder (CSIDL_INTERNET_CACHE);
+ cache_dir = get_special_folder (&FOLDERID_InternetCache);
#endif
if (!cache_dir || !cache_dir[0])
{
@@ -1858,7 +1865,7 @@ g_build_user_cache_dir (void)
* If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
* repository for temporary Internet files is used instead. A typical path is
* `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
- * See the [documentation for `CSIDL_INTERNET_CACHE`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_internet_cache).
+ * See the [documentation for `FOLDERID_InternetCache`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
*
* The return value is cached and modifying it at runtime is not supported, as
* it’s not thread-safe to modify environment variables at runtime.
@@ -1965,69 +1972,22 @@ load_user_special_dirs (void)
static void
load_user_special_dirs (void)
{
- typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid,
- DWORD dwFlags,
- HANDLE hToken,
- PWSTR *ppszPath);
- t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
+ g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (&FOLDERID_Desktop);
+ g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (&FOLDERID_Documents);
- static const GUID FOLDERID_Downloads =
- { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
- static const GUID FOLDERID_Public =
- { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
+ g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Downloads);
+ if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
+ g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Desktop);
- wchar_t *wcp;
-
- p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandleW (L"shell32.dll"),
- "SHGetKnownFolderPath");
-
- g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
- g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL);
-
- if (p_SHGetKnownFolderPath == NULL)
- {
- g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
- }
- else
- {
- wcp = NULL;
- (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp);
- if (wcp)
- {
- g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
- if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
- g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
- CoTaskMemFree (wcp);
- }
- else
- g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
- }
+ g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (&FOLDERID_Music);
+ g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (&FOLDERID_Pictures);
- g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC);
- g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES);
+ g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_Public);
+ if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
+ g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_PublicDocuments);
- if (p_SHGetKnownFolderPath == NULL)
- {
- /* XXX */
- g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
- }
- else
- {
- wcp = NULL;
- (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp);
- if (wcp)
- {
- g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
- if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
- g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
- CoTaskMemFree (wcp);
- }
- else
- g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
- }
-
- g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES);
- g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO);
+ g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (&FOLDERID_Templates);
+ g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (&FOLDERID_Videos);
}
#else /* default is unix */
@@ -2379,12 +2339,12 @@ g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
/* Documents and Settings\All Users\Application Data */
- p = get_special_folder (CSIDL_COMMON_APPDATA);
+ p = get_special_folder (&FOLDERID_ProgramData);
if (p)
g_array_append_val (data_dirs, p);
/* Documents and Settings\All Users\Documents */
- p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
+ p = get_special_folder (&FOLDERID_PublicDocuments);
if (p)
g_array_append_val (data_dirs, p);
@@ -2531,8 +2491,8 @@ g_build_system_data_dirs (void)
* the first elements in the list are the Application Data
* and Documents folders for All Users. (These can be determined only
* on Windows 2000 or later and are not present in the list on other
- * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
- * CSIDL_COMMON_DOCUMENTS.
+ * Windows versions.) See documentation for FOLDERID_ProgramData and
+ * FOLDERID_PublicDocuments.
*
* Then follows the "share" subfolder in the installation folder for
* the package containing the DLL that calls this function, if it can
@@ -2587,7 +2547,7 @@ g_build_system_config_dirs (void)
}
else
{
- gchar *special_conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
+ gchar *special_conf_dirs = get_special_folder (&FOLDERID_ProgramData);
if (special_conf_dirs)
conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
@@ -2625,7 +2585,7 @@ g_build_system_config_dirs (void)
* This folder is used for application data
* that is not user specific. For example, an application can store
* a spell-check dictionary, a database of clip art, or a log file in the
- * CSIDL_COMMON_APPDATA folder. This information will not roam and is available
+ * FOLDERID_ProgramData folder. This information will not roam and is available
* to anyone using the computer.
*
* The return value is cached and modifying it at runtime is not supported, as
diff --git a/glib/guuid.c b/glib/guuid.c
index f26343ee0..5368465c5 100644
--- a/glib/guuid.c
+++ b/glib/guuid.c
@@ -113,7 +113,7 @@ uuid_parse_string (const gchar *str,
if (hi == -1 || lo == -1)
return FALSE;
- bytes[i++] = hi << 8 | lo;
+ bytes[i++] = hi << 4 | lo;
}
if (uuid != NULL)
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index b34ba8d8e..a31d396dd 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -81,22 +81,22 @@ struct _GVariant
/* struct GVariant:
*
- * There are two primary forms of GVariant instances: "serialised form"
+ * There are two primary forms of GVariant instances: "serialized form"
* and "tree form".
*
- * "serialised form": A serialised GVariant instance stores its value in
- * the GVariant serialisation format. All
+ * "serialized form": A serialized GVariant instance stores its value in
+ * the GVariant serialization format. All
* basic-typed instances (ie: non-containers) are in
- * serialised format, as are some containers.
+ * serialized format, as are some containers.
*
* "tree form": Some containers are in "tree form". In this case,
- * instead of containing the serialised data for the
+ * instead of containing the serialized data for the
* container, the instance contains an array of pointers to
* the child values of the container (thus forming a tree).
*
* It is possible for an instance to transition from tree form to
- * serialised form. This happens, implicitly, if the serialised data is
- * requested (eg: via g_variant_get_data()). Serialised form instances
+ * serialized form. This happens, implicitly, if the serialized data is
+ * requested (eg: via g_variant_get_data()). Serialized form instances
* never transition into tree form.
*
*
@@ -109,8 +109,8 @@ struct _GVariant
* The type_info field never changes during the life of the
* instance, so it can be accessed without a lock.
*
- * size: this is the size of the serialised form for the instance, if it
- * is known. If the instance is in serialised form then it is, by
+ * size: this is the size of the serialized form for the instance, if it
+ * is known. If the instance is in serialized form then it is, by
* definition, known. If the instance is in tree form then it may
* be unknown (in which case it is -1). It is possible for the
* size to be known when in tree form if, for example, the user
@@ -126,33 +126,33 @@ struct _GVariant
* that, the size field can be accessed without a lock.
*
* contents: a union containing either the information associated with
- * holding a value in serialised form or holding a value in
+ * holding a value in serialized form or holding a value in
* tree form.
*
- * .serialised: Only valid when the instance is in serialised form.
+ * .serialised: Only valid when the instance is in serialized form.
*
* Since an instance can never transition away from
- * serialised form, once these fields are set, they will
+ * serialized form, once these fields are set, they will
* never be changed. It is therefore valid to access
* them without holding a lock.
*
* .bytes: the #GBytes that contains the memory pointed to by
* .data, or %NULL if .data is %NULL. In the event that
- * the instance was deserialised from another instance,
+ * the instance was deserialized from another instance,
* then the bytes will be shared by both of them. When
* the instance is freed, this reference must be released
* with g_bytes_unref().
*
- * .data: the serialised data (of size 'size') of the instance.
+ * .data: the serialized data (of size 'size') of the instance.
* This pointer should not be freed or modified in any way.
* #GBytes is responsible for memory management.
*
* This pointer may be %NULL in two cases:
*
- * - if the serialised size of the instance is 0
+ * - if the serialized size of the instance is 0
*
* - if the instance is of a fixed-sized type and was
- * deserialised out of a corrupted container such that
+ * deserialized out of a corrupted container such that
* the container contains too few bytes to point to the
* entire proper fixed-size of this instance. In this
* case, 'size' will still be equal to the proper fixed
@@ -165,12 +165,12 @@ struct _GVariant
* .tree: Only valid when the instance is in tree form.
*
* Note that accesses from other threads could result in
- * conversion of the instance from tree form to serialised form
+ * conversion of the instance from tree form to serialized form
* at any time. For this reason, the instance lock must always
* be held while performing any operations on 'contents.tree'.
*
* .children: the array of the child instances of this instance.
- * When the instance is freed (or converted to serialised
+ * When the instance is freed (or converted to serialized
* form) then each child must have g_variant_unref()
* called on it and the array must be freed using
* g_free().
@@ -183,18 +183,18 @@ struct _GVariant
* STATE_LOCKED: the instance lock is held. This is the bit used by
* g_bit_lock().
*
- * STATE_SERIALISED: the instance is in serialised form. If this
+ * STATE_SERIALISED: the instance is in serialized form. If this
* flag is not set then the instance is in tree
* form.
*
- * STATE_TRUSTED: for serialised form instances, this means that the
- * serialised data is known to be in normal form (ie:
+ * STATE_TRUSTED: for serialized form instances, this means that the
+ * serialized data is known to be in normal form (ie:
* not corrupted).
*
* For tree form instances, this means that all of the
* child instances in the contents.tree.children array
* are trusted. This means that if the container is
- * serialised then the resulting data will be in
+ * serialized then the resulting data will be in
* normal form.
*
* If this flag is unset it does not imply that the
@@ -209,7 +209,7 @@ struct _GVariant
* depth: the depth of the GVariant in a hierarchy of nested containers,
* increasing with the level of nesting. The top-most GVariant has depth
* zero. This is used to avoid recursing too deeply and overflowing the
- * stack when handling deeply nested untrusted serialised GVariants.
+ * stack when handling deeply nested untrusted serialized GVariants.
*/
#define STATE_LOCKED 1
#define STATE_SERIALISED 2
@@ -249,7 +249,7 @@ g_variant_unlock (GVariant *value)
* @value and frees the array itself. @value must be in tree form.
*
* This is done when freeing a tree-form instance or converting it to
- * serialised form.
+ * serialized form.
*
* The current thread must hold the lock on @value.
*/
@@ -267,52 +267,52 @@ g_variant_release_children (GVariant *value)
g_free (value->contents.tree.children);
}
-/* This begins the main body of the recursive serialiser.
+/* This begins the main body of the recursive serializer.
*
- * There are 3 functions here that work as a team with the serialiser to
+ * There are 3 functions here that work as a team with the serializer to
* get things done. g_variant_store() has a trivial role, but as a
* public API function, it has its definition elsewhere.
*
- * Note that "serialisation" of an instance does not mean that the
- * instance is converted to serialised form -- it means that the
- * serialised form of an instance is written to an external buffer.
+ * Note that "serialization" of an instance does not mean that the
+ * instance is converted to serialized form -- it means that the
+ * serialized form of an instance is written to an external buffer.
* g_variant_ensure_serialised() (which is not part of this set of
* functions) is the function that is responsible for converting an
- * instance to serialised form.
+ * instance to serialized form.
*
* We are only concerned here with container types since non-container
- * instances are always in serialised form. For these instances,
- * storing their serialised form merely involves a memcpy().
+ * instances are always in serialized form. For these instances,
+ * storing their serialized form merely involves a memcpy().
*
- * Serialisation is a two-step process. First, the size of the
- * serialised data must be calculated so that an appropriately-sized
+ * Serialization is a two-step process. First, the size of the
+ * serialized data must be calculated so that an appropriately-sized
* buffer can be allocated. Second, the data is written into the
* buffer.
*
* Determining the size:
* The process of determining the size is triggered by a call to
* g_variant_ensure_size() on a container. This invokes the
- * serialiser code to determine the size. The serialiser is passed
+ * serializer code to determine the size. The serializer is passed
* g_variant_fill_gvs() as a callback.
*
- * g_variant_fill_gvs() is called by the serialiser on each child of
+ * g_variant_fill_gvs() is called by the serializer on each child of
* the container which, in turn, calls g_variant_ensure_size() on
* itself and fills in the result of its own size calculation.
*
- * The serialiser uses the size information from the children to
+ * The serializer uses the size information from the children to
* calculate the size needed for the entire container.
*
* Writing the data:
* After the buffer has been allocated, g_variant_serialise() is
- * called on the container. This invokes the serialiser code to write
- * the bytes to the container. The serialiser is, again, passed
+ * called on the container. This invokes the serializer code to write
+ * the bytes to the container. The serializer is, again, passed
* g_variant_fill_gvs() as a callback.
*
* This time, when g_variant_fill_gvs() is called for each child, the
* child is given a pointer to a sub-region of the allocated buffer
* where it should write its data. This is done by calling
- * g_variant_store(). In the event that the instance is in serialised
- * form this means a memcpy() of the serialised data into the
+ * g_variant_store(). In the event that the instance is in serialized
+ * form this means a memcpy() of the serialized data into the
* allocated buffer. In the event that the instance is in tree form
* this means a recursive call back into g_variant_serialise().
*
@@ -326,7 +326,7 @@ static void g_variant_fill_gvs (GVariantSerialised *, gpointer);
* @value: a #GVariant
*
* Ensures that the ->size field of @value is filled in properly. This
- * must be done as a precursor to any serialisation of the value in
+ * must be done as a precursor to any serialization of the value in
* order to know how large of a buffer is needed to store the data.
*
* The current thread must hold the lock on @value.
@@ -354,7 +354,7 @@ g_variant_ensure_size (GVariant *value)
* @value: a #GVariant
* @data: an appropriately-sized buffer
*
- * Serialises @value into @data. @value must be in tree form.
+ * Serializes @value into @data. @value must be in tree form.
*
* No change is made to @value.
*
@@ -389,15 +389,15 @@ g_variant_serialise (GVariant *value,
* @data: a #GVariant instance
*
* This is the callback that is passed by a tree-form container instance
- * to the serialiser. This callback gets called on each child of the
+ * to the serializer. This callback gets called on each child of the
* container. Each child is responsible for performing the following
* actions:
*
* - reporting its type
*
- * - reporting its serialised size (requires knowing the size first)
+ * - reporting its serialized size (requires knowing the size first)
*
- * - possibly storing its serialised form into the provided buffer
+ * - possibly storing its serialized form into the provided buffer
*/
static void
g_variant_fill_gvs (GVariantSerialised *serialised,
@@ -425,18 +425,18 @@ g_variant_fill_gvs (GVariantSerialised *serialised,
g_variant_store (value, serialised->data);
}
-/* this ends the main body of the recursive serialiser */
+/* this ends the main body of the recursive serializer */
/* < private >
* g_variant_ensure_serialised:
* @value: a #GVariant
*
- * Ensures that @value is in serialised form.
+ * Ensures that @value is in serialized form.
*
* If @value is in tree form then this function ensures that the
- * serialised size is known and then allocates a buffer of that size and
- * serialises the instance into the buffer. The 'children' array is
- * then released and the instance is set to serialised form based on the
+ * serialized size is known and then allocates a buffer of that size and
+ * serializes the instance into the buffer. The 'children' array is
+ * then released and the instance is set to serialized form based on the
* contents of the buffer.
*
* The current thread must hold the lock on @value.
@@ -501,8 +501,8 @@ g_variant_alloc (const GVariantType *type,
* @bytes: a #GBytes
* @trusted: if the contents of @bytes are trusted
*
- * Constructs a new serialised-mode #GVariant instance. This is the
- * inner interface for creation of new serialised values that gets
+ * Constructs a new serialized-mode #GVariant instance. This is the
+ * inner interface for creation of new serialized values that gets
* called from various functions in gvariant.c.
*
* A reference is taken on @bytes.
@@ -605,7 +605,7 @@ g_variant_new_from_bytes (const GVariantType *type,
* @trusted: %TRUE if every child in @children in trusted
*
* Constructs a new tree-mode #GVariant instance. This is the inner
- * interface for creation of new serialised values that gets called from
+ * interface for creation of new serialized values that gets called from
* various functions in gvariant.c.
*
* @children is consumed by this function. g_free() will be called on
@@ -872,13 +872,13 @@ g_variant_is_floating (GVariant *value)
* If @value has a fixed-sized type then this function always returned
* that fixed size.
*
- * In the case that @value is already in serialised form or the size has
+ * In the case that @value is already in serialized form or the size has
* already been calculated (ie: this function has been called before)
* then this function is O(1). Otherwise, the size is calculated, an
* operation which is approximately O(n) in the number of values
* involved.
*
- * Returns: the serialised size of @value
+ * Returns: the serialized size of @value
*
* Since: 2.24
**/
@@ -896,33 +896,33 @@ g_variant_get_size (GVariant *value)
* g_variant_get_data:
* @value: a #GVariant instance
*
- * Returns a pointer to the serialised form of a #GVariant instance.
+ * Returns a pointer to the serialized form of a #GVariant instance.
* The returned data may not be in fully-normalised form if read from an
* untrusted source. The returned data must not be freed; it remains
* valid for as long as @value exists.
*
- * If @value is a fixed-sized value that was deserialised from a
- * corrupted serialised container then %NULL may be returned. In this
+ * If @value is a fixed-sized value that was deserialized from a
+ * corrupted serialized container then %NULL may be returned. In this
* case, the proper thing to do is typically to use the appropriate
* number of nul bytes in place of @value. If @value is not fixed-sized
* then %NULL is never returned.
*
- * In the case that @value is already in serialised form, this function
- * is O(1). If the value is not already in serialised form,
- * serialisation occurs implicitly and is approximately O(n) in the size
+ * In the case that @value is already in serialized form, this function
+ * is O(1). If the value is not already in serialized form,
+ * serialization occurs implicitly and is approximately O(n) in the size
* of the result.
*
- * To deserialise the data returned by this function, in addition to the
- * serialised data, you must know the type of the #GVariant, and (if the
+ * To deserialize the data returned by this function, in addition to the
+ * serialized data, you must know the type of the #GVariant, and (if the
* machine might be different) the endianness of the machine that stored
* it. As a result, file formats or network messages that incorporate
- * serialised #GVariants must include this information either
+ * serialized #GVariants must include this information either
* implicitly (for instance "the file always contains a
* %G_VARIANT_TYPE_VARIANT and it is always in little-endian order") or
* explicitly (by storing the type and/or endianness in addition to the
- * serialised data).
+ * serialized data).
*
- * Returns: (transfer none): the serialised form of @value, or %NULL
+ * Returns: (transfer none): the serialized form of @value, or %NULL
*
* Since: 2.24
**/
@@ -940,7 +940,7 @@ g_variant_get_data (GVariant *value)
* g_variant_get_data_as_bytes:
* @value: a #GVariant
*
- * Returns a pointer to the serialised form of a #GVariant instance.
+ * Returns a pointer to the serialized form of a #GVariant instance.
* The semantics of this function are exactly the same as
* g_variant_get_data(), except that the returned #GBytes holds
* a reference to the variant data.
@@ -1043,7 +1043,7 @@ g_variant_n_children (GVariant *value)
*
* Note that values borrowed from the returned child are not guaranteed to
* still be valid after the child is freed even if you still hold a reference
- * to @value, if @value has not been serialised at the time this function is
+ * to @value, if @value has not been serialized at the time this function is
* called. To avoid this, you can serialize @value by calling
* g_variant_get_data() and optionally ignoring the return value.
*
@@ -1092,8 +1092,8 @@ g_variant_get_child_value (GVariant *value,
GVariantSerialised s_child;
GVariant *child;
- /* get the serialiser to extract the serialised data for the child
- * from the serialised data for the container
+ /* get the serializer to extract the serialized data for the child
+ * from the serialized data for the container
*/
s_child = g_variant_serialised_get_child (serialised, index_);
@@ -1111,7 +1111,7 @@ g_variant_get_child_value (GVariant *value,
return g_variant_new_tuple (NULL, 0);
}
- /* create a new serialised instance out of it */
+ /* create a new serialized instance out of it */
child = g_slice_new (GVariant);
child->type_info = s_child.type_info;
child->state = (value->state & STATE_TRUSTED) |
@@ -1130,17 +1130,17 @@ g_variant_get_child_value (GVariant *value,
/**
* g_variant_store:
* @value: the #GVariant to store
- * @data: (not nullable): the location to store the serialised data at
+ * @data: (not nullable): the location to store the serialized data at
*
- * Stores the serialised form of @value at @data. @data should be
+ * Stores the serialized form of @value at @data. @data should be
* large enough. See g_variant_get_size().
*
* The stored data is in machine native byte order but may not be in
* fully-normalised form if read from an untrusted source. See
* g_variant_get_normal_form() for a solution.
*
- * As with g_variant_get_data(), to be able to deserialise the
- * serialised variant successfully, its type and (if the destination
+ * As with g_variant_get_data(), to be able to deserialize the
+ * serialized variant successfully, its type and (if the destination
* machine might be different) its endianness must also be available.
*
* This function is approximately O(n) in the size of @data.
@@ -1173,7 +1173,7 @@ g_variant_store (GVariant *value,
* Checks if @value is in normal form.
*
* The main reason to do this is to detect if a given chunk of
- * serialised data is in normal form: load the data into a #GVariant
+ * serialized data is in normal form: load the data into a #GVariant
* using g_variant_new_from_data() and then use this function to
* check.
*
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 06f419fe4..832a8fdc2 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -44,26 +44,26 @@
* container and implements 5 functions for dealing with it:
*
* n_children:
- * - determines (according to serialised data) how many child values
+ * - determines (according to serialized data) how many child values
* are inside a particular container value.
*
* get_child:
- * - gets the type of and the serialised data corresponding to a
+ * - gets the type of and the serialized data corresponding to a
* given child value within the container value.
*
* needed_size:
- * - determines how much space would be required to serialise a
+ * - determines how much space would be required to serialize a
* container of this type, containing the given children so that
- * buffers can be preallocated before serialising.
+ * buffers can be preallocated before serializing.
*
* serialise:
- * - write the serialised data for a container of this type,
+ * - write the serialized data for a container of this type,
* containing the given children, to a buffer.
*
* is_normal:
* - check the given data to ensure that it is in normal form. For a
* given set of child values, there is exactly one normal form for
- * the serialised data of a container. Other forms are possible
+ * the serialized data of a container. Other forms are possible
* while maintaining the same children (for example, by inserting
* something other than zero bytes as padding) but only one form is
* the normal form.
@@ -72,7 +72,7 @@
* functions and logic to dispatch it to the handler for the appropriate
* container type code.
*
- * The second part also contains a routine to byteswap serialised
+ * The second part also contains a routine to byteswap serialized
* values. This code makes use of the n_children() and get_child()
* functions above to do its work so no extra support is needed on a
* per-container-type basis.
@@ -90,17 +90,17 @@
/* < private >
* GVariantSerialised:
* @type_info: the #GVariantTypeInfo of this value
- * @data: (nullable): the serialised data of this value, or %NULL
+ * @data: (nullable): the serialized data of this value, or %NULL
* @size: the size of this value
*
- * A structure representing a GVariant in serialised form. This
+ * A structure representing a GVariant in serialized form. This
* structure is used with #GVariantSerialisedFiller functions and as the
- * primary interface to the serialiser. See #GVariantSerialisedFiller
+ * primary interface to the serializer. See #GVariantSerialisedFiller
* for a description of its use there.
*
- * When used with the serialiser API functions, the following invariants
+ * When used with the serializer API functions, the following invariants
* apply to all #GVariantTypeSerialised structures passed to and
- * returned from the serialiser.
+ * returned from the serializer.
*
* @type_info must be non-%NULL.
*
@@ -117,7 +117,7 @@
* combination should be as if @data were a pointer to an
* appropriately-sized zero-filled region.
*
- * @depth has no restrictions; the depth of a top-level serialised #GVariant is
+ * @depth has no restrictions; the depth of a top-level serialized #GVariant is
* zero, and it increases for each level of nested child.
*/
@@ -185,9 +185,9 @@ g_variant_serialised_check (GVariantSerialised serialised)
* from a partially-complete #GVariantSerialised.
*
* The @data parameter passed back to the function is one of the items
- * that was passed to the serialiser in the @children array. It
+ * that was passed to the serializer in the @children array. It
* represents a single child item of the container that is being
- * serialised. The information filled in to @serialised is the
+ * serialized. The information filled in to @serialised is the
* information for this child.
*
* If the @type_info field of @serialised is %NULL then the callback
@@ -197,24 +197,24 @@ g_variant_serialised_check (GVariantSerialised serialised)
* of the child.
*
* If the @size field is zero then the callback must fill it in with the
- * required amount of space to store the serialised form of the child.
+ * required amount of space to store the serialized form of the child.
* If it is non-zero then the callback should assert that it is equal to
* the needed size of the child.
*
* If @data is non-%NULL then it points to a space that is properly
- * aligned for and large enough to store the serialised data of the
- * child. The callback must store the serialised form of the child at
+ * aligned for and large enough to store the serialized data of the
+ * child. The callback must store the serialized form of the child at
* @data.
*
* If the child value is another container then the callback will likely
- * recurse back into the serialiser by calling
+ * recurse back into the serializer by calling
* g_variant_serialiser_needed_size() to determine @size and
* g_variant_serialiser_serialise() to write to @data.
*/
/* PART 1: Container types {{{1
*
- * This section contains the serialiser implementation functions for
+ * This section contains the serializer implementation functions for
* each container type.
*/
@@ -235,7 +235,7 @@ g_variant_serialised_check (GVariantSerialised serialised)
* size of the maybe value is zero corresponds to the "Nothing" case and
* the case where the size of the maybe value is equal to the fixed size
* of the element type corresponds to the "Just" case; in that case, the
- * serialised data of the child value forms the entire serialised data
+ * serialized data of the child value forms the entire serialized data
* of the maybe value.
*
* In the event that a fixed-sized maybe value is presented with a size
@@ -331,11 +331,11 @@ gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
* either 0 or strictly greater than 0. The case where the size of the
* maybe value is zero corresponds to the "Nothing" case and the case
* where the size of the maybe value is greater than zero corresponds to
- * the "Just" case; in that case, the serialised data of the child value
- * forms the first part of the serialised data of the maybe value and is
+ * the "Just" case; in that case, the serialized data of the child value
+ * forms the first part of the serialized data of the maybe value and is
* followed by a single zero byte. This zero byte is always appended,
* regardless of any zero bytes that may already be at the end of the
- * serialised ata of the child value.
+ * serialized ata of the child value.
*/
static gsize
@@ -424,8 +424,8 @@ gvs_variable_sized_maybe_is_normal (GVariantSerialised value)
/* Fixed-sized Array {{{3
*
- * For fixed sized arrays, the serialised data is simply a concatenation
- * of the serialised data of each element, in order. Since fixed-sized
+ * For fixed sized arrays, the serialized data is simply a concatenation
+ * of the serialized data of each element, in order. Since fixed-sized
* values always have a fixed size that is a multiple of their alignment
* requirement no extra padding is required.
*
@@ -535,35 +535,35 @@ gvs_fixed_sized_array_is_normal (GVariantSerialised value)
* record the end point of each element in the array.
*
* GVariant works in terms of "offsets". An offset is a pointer to a
- * boundary between two bytes. In 4 bytes of serialised data, there
+ * boundary between two bytes. In 4 bytes of serialized data, there
* would be 5 possible offsets: one at the start ('0'), one between each
* pair of adjacent bytes ('1', '2', '3') and one at the end ('4').
*
* The numeric value of an offset is an unsigned integer given relative
- * to the start of the serialised data of the array. Offsets are always
+ * to the start of the serialized data of the array. Offsets are always
* stored in little endian byte order and are always only as big as they
- * need to be. For example, in 255 bytes of serialised data, there are
+ * need to be. For example, in 255 bytes of serialized data, there are
* 256 offsets. All possibilities can be stored in an 8 bit unsigned
- * integer. In 256 bytes of serialised data, however, there are 257
+ * integer. In 256 bytes of serialized data, however, there are 257
* possible offsets so 16 bit integers must be used. The size of an
* offset is always a power of 2.
*
- * The offsets are stored at the end of the serialised data of the
+ * The offsets are stored at the end of the serialized data of the
* array. They are simply concatenated on without any particular
* alignment. The size of the offsets is included in the size of the
- * serialised data for purposes of determining the size of the offsets.
+ * serialized data for purposes of determining the size of the offsets.
* This presents a possibly ambiguity; in certain cases, a particular
- * value of array could have two different serialised forms.
+ * value of array could have two different serialized forms.
*
* Imagine an array containing a single string of 253 bytes in length
* (so, 254 bytes including the nul terminator). Now the offset must be
* written. If an 8 bit offset is written, it will bring the size of
- * the array's serialised data to 255 -- which means that the use of an
+ * the array's serialized data to 255 -- which means that the use of an
* 8 bit offset was valid. If a 16 bit offset is used then the total
* size of the array will be 256 -- which means that the use of a 16 bit
* offset was valid. Although both of these will be accepted by the
- * deserialiser, only the smaller of the two is considered to be in
- * normal form and that is the one that the serialiser must produce.
+ * deserializer, only the smaller of the two is considered to be in
+ * normal form and that is the one that the serializer must produce.
*/
/* bytes may be NULL if (size == 0). */
@@ -840,20 +840,20 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
/* Tuples {{{2
*
* Since tuples can contain a mix of variable- and fixed-sized items,
- * they are, in terms of serialisation, a hybrid of variable-sized and
+ * they are, in terms of serialization, a hybrid of variable-sized and
* fixed-sized arrays.
*
* Offsets are only stored for variable-sized items. Also, since the
* number of items in a tuple is known from its type, we are able to
- * know exactly how many offsets to expect in the serialised data (and
+ * know exactly how many offsets to expect in the serialized data (and
* therefore how much space is taken up by the offset array). This
- * means that we know where the end of the serialised data for the last
+ * means that we know where the end of the serialized data for the last
* item is -- we can just subtract the size of the offset array from the
* total size of the tuple. For this reason, the last item in the tuple
* doesn't need an offset stored.
*
* Tuple offsets are stored in reverse. This design choice allows
- * iterator-based deserialisers to be more efficient.
+ * iterator-based deserializers to be more efficient.
*
* Most of the "heavy lifting" here is handled by the GVariantTypeInfo
* for the tuple. See the notes in gvarianttypeinfo.h.
@@ -1158,7 +1158,7 @@ gvs_tuple_is_normal (GVariantSerialised value)
/* Variants {{{2
*
- * Variants are stored by storing the serialised data of the child,
+ * Variants are stored by storing the serialized data of the child,
* followed by a '\0' character, followed by the type string of the
* child.
*
@@ -1287,9 +1287,9 @@ gvs_variant_is_normal (GVariantSerialised value)
-/* PART 2: Serialiser API {{{1
+/* PART 2: Serializer API {{{1
*
- * This is the implementation of the API of the serialiser as advertised
+ * This is the implementation of the API of the serializer as advertised
* in gvariant-serialiser.h.
*/
@@ -1338,9 +1338,9 @@ gvs_variant_is_normal (GVariantSerialised value)
} \
}
-/* Serialiser entry points {{{2
+/* Serializer entry points {{{2
*
- * These are the functions that are called in order for the serialiser
+ * These are the functions that are called in order for the serializer
* to do its thing.
*/
@@ -1348,7 +1348,7 @@ gvs_variant_is_normal (GVariantSerialised value)
* g_variant_serialised_n_children:
* @serialised: a #GVariantSerialised
*
- * For serialised data that represents a container value (maybes,
+ * For serialized data that represents a container value (maybes,
* tuples, arrays, variants), determine how many child items are inside
* that container.
*
@@ -1372,7 +1372,7 @@ g_variant_serialised_n_children (GVariantSerialised serialised)
* @serialised: a #GVariantSerialised
* @index_: the index of the child to fetch
*
- * Extracts a child from a serialised data representing a container
+ * Extracts a child from a serialized data representing a container
* value.
*
* It is an error to call this function with an index out of bounds.
@@ -1421,19 +1421,19 @@ g_variant_serialised_get_child (GVariantSerialised serialised,
* @children: an array of child items
* @n_children: the size of @children
*
- * Writes data in serialised form.
+ * Writes data in serialized form.
*
* The type_info field of @serialised must be filled in to type info for
- * the type that we are serialising.
+ * the type that we are serializing.
*
* The size field of @serialised must be filled in with the value
* returned by a previous call to g_variant_serialiser_needed_size().
*
* The data field of @serialised must be a pointer to a properly-aligned
- * memory region large enough to serialise into (ie: at least as big as
+ * memory region large enough to serialize into (ie: at least as big as
* the size field).
*
- * This function is only resonsible for serialising the top-level
+ * This function is only resonsible for serializing the top-level
* container. @gvs_filler is called on each child of the container in
* order for all of the data of that child to be filled in.
*/
@@ -1457,12 +1457,12 @@ g_variant_serialiser_serialise (GVariantSerialised serialised,
/* < private >
* g_variant_serialiser_needed_size:
- * @type_info: the type to serialise for
+ * @type_info: the type to serialize for
* @gvs_filler: the filler function
* @children: an array of child items
* @n_children: the size of @children
*
- * Determines how much memory would be needed to serialise this value.
+ * Determines how much memory would be needed to serialize this value.
*
* This function is only resonsible for performing calculations for the
* top-level container. @gvs_filler is called on each child of the
@@ -1489,7 +1489,7 @@ g_variant_serialiser_needed_size (GVariantTypeInfo *type_info,
* g_variant_serialised_byteswap:
* @value: a #GVariantSerialised
*
- * Byte-swap serialised data. The result of this function is only
+ * Byte-swap serialized data. The result of this function is only
* well-defined if the data is in normal form.
*/
void
@@ -1577,9 +1577,9 @@ g_variant_serialised_byteswap (GVariantSerialised serialised)
* @serialised: a #GVariantSerialised
*
* Determines, recursively if @serialised is in normal form. There is
- * precisely one normal form of serialised data for each possible value.
+ * precisely one normal form of serialized data for each possible value.
*
- * It is possible that multiple byte sequences form the serialised data
+ * It is possible that multiple byte sequences form the serialized data
* for a given value if, for example, the padding bytes are filled in
* with something other than zeros, but only one form is the normal
* form.
diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h
index 81343e9ca..859cb7bfe 100644
--- a/glib/gvariant-serialiser.h
+++ b/glib/gvariant-serialiser.h
@@ -31,14 +31,14 @@ typedef struct
gsize depth; /* same semantics as GVariant.depth */
} GVariantSerialised;
-/* deserialisation */
+/* deserialization */
GLIB_AVAILABLE_IN_ALL
gsize g_variant_serialised_n_children (GVariantSerialised container);
GLIB_AVAILABLE_IN_ALL
GVariantSerialised g_variant_serialised_get_child (GVariantSerialised container,
gsize index);
-/* serialisation */
+/* serialization */
typedef void (*GVariantSerialisedFiller) (GVariantSerialised *serialised,
gpointer data);
diff --git a/glib/gvariant.c b/glib/gvariant.c
index e48dec1ad..a9bb99c64 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -84,19 +84,19 @@
* concurrently accessed in any way from any number of threads without
* problems.
*
- * #GVariant is heavily optimised for dealing with data in serialised
+ * #GVariant is heavily optimised for dealing with data in serialized
* form. It works particularly well with data located in memory-mapped
- * files. It can perform nearly all deserialisation operations in a
+ * files. It can perform nearly all deserialization operations in a
* small constant time, usually touching only a single memory page.
- * Serialised #GVariant data can also be sent over the network.
+ * Serialized #GVariant data can also be sent over the network.
*
* #GVariant is largely compatible with D-Bus. Almost all types of
* #GVariant instances can be sent over D-Bus. See #GVariantType for
- * exceptions. (However, #GVariant's serialisation format is not the same
- * as the serialisation format of a D-Bus message body: use #GDBusMessage,
+ * exceptions. (However, #GVariant's serialization format is not the same
+ * as the serialization format of a D-Bus message body: use #GDBusMessage,
* in the gio library, for those.)
*
- * For space-efficiency, the #GVariant serialisation format does not
+ * For space-efficiency, the #GVariant serialization format does not
* automatically include the variant's length, type or endianness,
* which must either be implied from context (such as knowledge that a
* particular file format always contains a little-endian
@@ -126,14 +126,14 @@
* in the future.
*
* The memory allocated by #GVariant can be grouped into 4 broad
- * purposes: memory for serialised data, memory for the type
+ * purposes: memory for serialized data, memory for the type
* information cache, buffer management memory and memory for the
* #GVariant structure itself.
*
- * ## Serialised Data Memory
+ * ## Serialized Data Memory
*
* This is the memory that is used for storing GVariant data in
- * serialised form. This is what would be sent over the network or
+ * serialized form. This is what would be sent over the network or
* what would end up on disk, not counting any indicator of the
* endianness, or of the length or type of the top-level variant.
*
@@ -167,7 +167,7 @@
*
* As an example, consider a dictionary mapping strings to variants.
* In the case that the dictionary is empty, 0 bytes are required for
- * the serialisation.
+ * the serialization.
*
* If we add an item "width" that maps to the int32 value of 500 then
* we will use 4 byte to store the int32 (so 6 for the variant
@@ -193,7 +193,7 @@
*
* For each GVariant type that currently exists in the program a type
* information structure is kept in the type information cache. The
- * type information structure is required for rapid deserialisation.
+ * type information structure is required for rapid deserialization.
*
* Continuing with the above example, if a #GVariant exists with the
* type "a{sv}" then a type information struct will exist for
@@ -238,14 +238,14 @@
* ## Buffer Management Memory
*
* #GVariant uses an internal buffer management structure to deal
- * with the various different possible sources of serialised data
+ * with the various different possible sources of serialized data
* that it uses. The buffer is responsible for ensuring that the
* correct call is made when the data is no longer in use by
* #GVariant. This may involve a g_free() or a g_slice_free() or
* even g_mapped_file_unref().
*
* One buffer management structure is used for each chunk of
- * serialised data. The size of the buffer management structure
+ * serialized data. The size of the buffer management structure
* is 4 * (void *). On 32-bit systems, that's 16 bytes.
*
* ## GVariant structure
@@ -255,7 +255,7 @@
*
* #GVariant structures only exist if they are explicitly created
* with API calls. For example, if a #GVariant is constructed out of
- * serialised data for the example given above (with the dictionary)
+ * serialized data for the example given above (with the dictionary)
* then although there are 9 individual values that comprise the
* entire dictionary (two keys, two values, two variants containing
* the values, two dictionary entries, plus the dictionary itself),
@@ -265,8 +265,8 @@
* If calls are made to start accessing the other values then
* #GVariant instances will exist for those values only for as long
* as they are in use (ie: until you call g_variant_unref()). The
- * type information is shared. The serialised data and the buffer
- * management structure for that serialised data is shared by the
+ * type information is shared. The serialized data and the buffer
+ * management structure for that serialized data is shared by the
* child.
*
* ## Summary
@@ -274,12 +274,12 @@
* To put the entire example together, for our dictionary mapping
* strings to variants (with two entries, as given above), we are
* using 91 bytes of memory for type information, 29 bytes of memory
- * for the serialised data, 16 bytes for buffer management and 24
+ * for the serialized data, 16 bytes for buffer management and 24
* bytes for the #GVariant instance, or a total of 160 bytes, plus
* malloc overhead. If we were to use g_variant_get_child_value() to
* access the two dictionary entries, we would use an additional 48
* bytes. If we were to have other dictionaries of the same type, we
- * would use more memory for the serialised data and buffer
+ * would use more memory for the serialized data and buffer
* management for those dictionaries, but the type information would
* be shared.
*/
@@ -1095,7 +1095,7 @@ g_variant_lookup_value (GVariant *dictionary,
* @n_elements: (out): a pointer to the location to store the number of items
* @element_size: the size of each element
*
- * Provides access to the serialised data for an array of fixed-sized
+ * Provides access to the serialized data for an array of fixed-sized
* items.
*
* @value must be an array with fixed-sized elements. Numeric types are
@@ -1103,7 +1103,7 @@ g_variant_lookup_value (GVariant *dictionary,
*
* @element_size must be the size of a single element in the array,
* as given by the section on
- * [serialized data memory][gvariant-serialised-data-memory].
+ * [serialized data memory][gvariant-serialized-data-memory].
*
* In particular, arrays of these fixed-sized types can be interpreted
* as an array of the given C type, with @element_size set to the size
@@ -1116,7 +1116,7 @@ g_variant_lookup_value (GVariant *dictionary,
*
* For example, if calling this function for an array of 32-bit integers,
* you might say `sizeof(gint32)`. This value isn't used except for the purpose
- * of a double-check that the form of the serialised data matches the caller's
+ * of a double-check that the form of the serialized data matches the caller's
* expectation.
*
* @n_elements, which must be non-%NULL, is set equal to the number of
@@ -1191,7 +1191,7 @@ g_variant_get_fixed_array (GVariant *value,
* @element_size must be the size of a single element in the array.
* For example, if calling this function for an array of 32-bit integers,
* you might say sizeof(gint32). This value isn't used except for the purpose
- * of a double-check that the form of the serialised data matches the caller's
+ * of a double-check that the form of the serialized data matches the caller's
* expectation.
*
* @n_elements must be the length of the @elements array.
@@ -2745,8 +2745,8 @@ g_variant_equal (gconstpointer one,
g_variant_get_type_info ((GVariant *) two))
return FALSE;
- /* if both values are trusted to be in their canonical serialised form
- * then a simple memcmp() of their serialised data will answer the
+ /* if both values are trusted to be in their canonical serialized form
+ * then a simple memcmp() of their serialized data will answer the
* question.
*
* if not, then this might generate a false negative (since it is
@@ -5793,7 +5793,7 @@ g_variant_iter_loop (GVariantIter *iter,
return value != NULL;
}
-/* Serialised data {{{1 */
+/* Serialized data {{{1 */
static GVariant *
g_variant_deep_copy (GVariant *value)
{
@@ -5882,7 +5882,7 @@ g_variant_deep_copy (GVariant *value)
* #GVariant is created with the same value as @value.
*
* It makes sense to call this function if you've received #GVariant
- * data from untrusted sources and you want to ensure your serialised
+ * data from untrusted sources and you want to ensure your serialized
* output is definitely in normal form.
*
* If @value is already in normal form, a new reference will be returned
@@ -5972,13 +5972,13 @@ g_variant_byteswap (GVariant *value)
/**
* g_variant_new_from_data:
* @type: a definite #GVariantType
- * @data: (array length=size) (element-type guint8): the serialised data
+ * @data: (array length=size) (element-type guint8): the serialized data
* @size: the size of @data
* @trusted: %TRUE if @data is definitely in normal form
* @notify: (scope async): function to call when @data is no longer needed
* @user_data: data for @notify
*
- * Creates a new #GVariant instance from serialised data.
+ * Creates a new #GVariant instance from serialized data.
*
* @type is the type of #GVariant instance that will be constructed.
* The interpretation of @data depends on knowing the type.
@@ -5988,8 +5988,8 @@ g_variant_byteswap (GVariant *value)
* @user_data. If the contents of @data change before that time then
* the result is undefined.
*
- * If @data is trusted to be serialised data in normal form then
- * @trusted should be %TRUE. This applies to serialised data created
+ * If @data is trusted to be serialized data in normal form then
+ * @trusted should be %TRUE. This applies to serialized data created
* within this process or read from a trusted location on the disk (such
* as a file installed in /usr/lib alongside your application). You
* should set trusted to %FALSE if @data is read from the network, a
diff --git a/glib/gvarianttypeinfo.c b/glib/gvarianttypeinfo.c
index 087294a09..6fdde8f8e 100644
--- a/glib/gvarianttypeinfo.c
+++ b/glib/gvarianttypeinfo.c
@@ -32,7 +32,7 @@
* GVariantTypeInfo:
*
* This structure contains the necessary information to facilitate the
- * serialisation and fast deserialisation of a given type of GVariant
+ * serialization and fast deserialization of a given type of GVariant
* value. A GVariant instance holds a pointer to one of these
* structures to provide for efficient operation.
*
@@ -93,7 +93,7 @@ typedef struct
} ArrayInfo;
/* For 'tuple' and 'dict entry' types, we store extra information for
- * each member -- its type and how to find it inside the serialised data
+ * each member -- its type and how to find it inside the serialized data
* in O(1) time using 4 variables -- 'i', 'a', 'b', and 'c'. See the
* comment on GVariantMemberInfo in gvarianttypeinfo.h.
*/
diff --git a/glib/gvarianttypeinfo.h b/glib/gvarianttypeinfo.h
index 8663e2090..cff0dba6e 100644
--- a/glib/gvarianttypeinfo.h
+++ b/glib/gvarianttypeinfo.h
@@ -40,18 +40,18 @@ typedef struct _GVariantTypeInfo GVariantTypeInfo;
* corresponding to a given child of a tuple or dictionary entry in a
* very short constant time. It contains the typeinfo of the child,
* along with 4 constants that allow the bounds of the child's
- * serialised data within the container's serialised data to be found
+ * serialized data within the container's serialized data to be found
* very efficiently.
*
- * Since dictionary entries are serialised as if they were tuples of 2
+ * Since dictionary entries are serialized as if they were tuples of 2
* items, the term "tuple" will be used here in the general sense to
* refer to tuples and dictionary entries.
*
* BACKGROUND:
- * The serialised data for a tuple contains an array of "offsets" at
+ * The serialized data for a tuple contains an array of "offsets" at
* the end. There is one "offset" in this array for each
* variable-sized item in the tuple (except for the last one). The
- * offset points to the end point of that item's serialised data. The
+ * offset points to the end point of that item's serialized data. The
* procedure for finding the start point is described below. An
* offset is not needed for the last item because the end point of the
* last item is merely the end point of the container itself (after
diff --git a/glib/gversionmacros.h b/glib/gversionmacros.h
index 77486eafb..d052709cf 100644
--- a/glib/gversionmacros.h
+++ b/glib/gversionmacros.h
@@ -256,6 +256,16 @@
#define GLIB_VERSION_2_68 (G_ENCODE_VERSION (2, 68))
/**
+ * GLIB_VERSION_2_70:
+ *
+ * A macro that evaluates to the 2.70 version of GLib, in a format
+ * that can be used by the C pre-processor.
+ *
+ * Since: 2.70
+ */
+#define GLIB_VERSION_2_70 (G_ENCODE_VERSION (2, 70))
+
+/**
* GLIB_VERSION_CUR_STABLE:
*
* A macro that evaluates to the current stable version of GLib, in a format
@@ -1076,4 +1086,38 @@
# define GLIB_AVAILABLE_TYPE_IN_2_68
#endif
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_70
+# define GLIB_DEPRECATED_IN_2_70 GLIB_DEPRECATED
+# define GLIB_DEPRECATED_IN_2_70_FOR(f) GLIB_DEPRECATED_FOR(f)
+# define GLIB_DEPRECATED_MACRO_IN_2_70 GLIB_DEPRECATED_MACRO
+# define GLIB_DEPRECATED_MACRO_IN_2_70_FOR(f) GLIB_DEPRECATED_MACRO_FOR(f)
+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70 GLIB_DEPRECATED_ENUMERATOR
+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR(f) GLIB_DEPRECATED_ENUMERATOR_FOR(f)
+# define GLIB_DEPRECATED_TYPE_IN_2_70 GLIB_DEPRECATED_TYPE
+# define GLIB_DEPRECATED_TYPE_IN_2_70_FOR(f) GLIB_DEPRECATED_TYPE_FOR(f)
+#else
+# define GLIB_DEPRECATED_IN_2_70 _GLIB_EXTERN
+# define GLIB_DEPRECATED_IN_2_70_FOR(f) _GLIB_EXTERN
+# define GLIB_DEPRECATED_MACRO_IN_2_70
+# define GLIB_DEPRECATED_MACRO_IN_2_70_FOR(f)
+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70
+# define GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR(f)
+# define GLIB_DEPRECATED_TYPE_IN_2_70
+# define GLIB_DEPRECATED_TYPE_IN_2_70_FOR(f)
+#endif
+
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_70
+# define GLIB_AVAILABLE_IN_2_70 GLIB_UNAVAILABLE(2, 70)
+# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 GLIB_UNAVAILABLE_STATIC_INLINE(2, 70)
+# define GLIB_AVAILABLE_MACRO_IN_2_70 GLIB_UNAVAILABLE_MACRO(2, 70)
+# define GLIB_AVAILABLE_ENUMERATOR_IN_2_70 GLIB_UNAVAILABLE_ENUMERATOR(2, 70)
+# define GLIB_AVAILABLE_TYPE_IN_2_70 GLIB_UNAVAILABLE_TYPE(2, 70)
+#else
+# define GLIB_AVAILABLE_IN_2_70 _GLIB_EXTERN
+# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
+# define GLIB_AVAILABLE_MACRO_IN_2_70
+# define GLIB_AVAILABLE_ENUMERATOR_IN_2_70
+# define GLIB_AVAILABLE_TYPE_IN_2_70
+#endif
+
#endif /* __G_VERSION_MACROS_H__ */
diff --git a/glib/gwin32-private.c b/glib/gwin32-private.c
index f7913b553..c28e92baa 100644
--- a/glib/gwin32-private.c
+++ b/glib/gwin32-private.c
@@ -18,16 +18,16 @@
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
* and @event for `%e`.
- * If @debugger_size (in bytes) is overflowed, return %FALSE.
+ * If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
* Also returns %FALSE when `%` is followed by anything other
* than `e` or `p`.
*/
static gboolean
-_g_win32_subst_pid_and_event (char *debugger,
- gsize debugger_size,
- const char *cmdline,
- DWORD pid,
- guintptr event)
+_g_win32_subst_pid_and_event_w (wchar_t *debugger,
+ gsize debugger_size,
+ const wchar_t *cmdline,
+ DWORD pid,
+ guintptr event)
{
gsize i = 0, dbg_i = 0;
/* These are integers, and they can't be longer than 20 characters
@@ -35,31 +35,31 @@ _g_win32_subst_pid_and_event (char *debugger,
* Use 30 just to be sure.
*/
#define STR_BUFFER_SIZE 30
- char pid_str[STR_BUFFER_SIZE] = {0};
+ wchar_t pid_str[STR_BUFFER_SIZE] = {0};
gsize pid_str_len;
- char event_str[STR_BUFFER_SIZE] = {0};
+ wchar_t event_str[STR_BUFFER_SIZE] = {0};
gsize event_str_len;
- _snprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), "%lu", pid);
+ _snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
- pid_str_len = strlen (pid_str);
- _snprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), "%Iu", event);
+ pid_str_len = wcslen (pid_str);
+ _snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
- event_str_len = strlen (event_str);
+ event_str_len = wcslen (event_str);
#undef STR_BUFFER_SIZE
while (cmdline[i] != 0 && dbg_i < debugger_size)
{
- if (cmdline[i] != '%')
+ if (cmdline[i] != L'%')
debugger[dbg_i++] = cmdline[i++];
- else if (cmdline[i + 1] == 'p')
+ else if (cmdline[i + 1] == L'p')
{
gsize j = 0;
while (j < pid_str_len && dbg_i < debugger_size)
debugger[dbg_i++] = pid_str[j++];
i += 2;
}
- else if (cmdline[i + 1] == 'e')
+ else if (cmdline[i + 1] == L'e')
{
gsize j = 0;
while (j < event_str_len && dbg_i < debugger_size)
diff --git a/glib/gwin32.c b/glib/gwin32.c
index b62f19461..f4590916f 100644
--- a/glib/gwin32.c
+++ b/glib/gwin32.c
@@ -1035,10 +1035,32 @@ g_console_win32_init (void)
* it will be non-NULL. Only used to later de-install the handler
* on library de-initialization.
*/
-static void *WinVEH_handle = NULL;
+static void *WinVEH_handle = NULL;
+
+#define DEBUGGER_BUFFER_SIZE (MAX_PATH + 1)
+/* This is the debugger that we'll run on crash */
+static wchar_t debugger[DEBUGGER_BUFFER_SIZE];
+
+static gsize number_of_exceptions_to_catch = 0;
+static DWORD *exceptions_to_catch = NULL;
+
+static HANDLE debugger_wakeup_event = 0;
+static DWORD debugger_spawn_flags = 0;
#include "gwin32-private.c"
+static char *
+copy_chars (char *buffer,
+ gsize *buffer_size,
+ const char *to_copy)
+{
+ gsize copy_count = MIN (strlen (to_copy), *buffer_size - 1);
+ memset (buffer, 0x20, copy_count);
+ strncpy_s (buffer, *buffer_size, to_copy, _TRUNCATE);
+ *buffer_size -= copy_count;
+ return &buffer[copy_count];
+}
+
/* Handles exceptions (useful for debugging).
* Issues a DebugBreak() call if the process is being debugged (not really
* useful - if the process is being debugged, this handler won't be invoked
@@ -1068,24 +1090,31 @@ static void *WinVEH_handle = NULL;
* or for control flow.
*
* This function deliberately avoids calling any GLib code.
+ * This is done on purpose. This function can be called when the program
+ * is in a bad state (crashing). It can also be called very early, as soon
+ * as the handler is installed. Therefore, it's imperative that
+ * it does as little as possible. Preferably, all the work that can be
+ * done in advance (when the program is not crashing yet) should be done
+ * in advance.
*/
static LONG __stdcall
g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
{
EXCEPTION_RECORD *er;
- char debugger[MAX_PATH + 1];
- WCHAR *debugger_utf16;
- const char *debugger_env = NULL;
- const char *catch_list;
- gboolean catch = FALSE;
+ gsize i;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
- HANDLE event;
- SECURITY_ATTRIBUTES sa;
+#define ITOA_BUFFER_SIZE 100
+ char itoa_buffer[ITOA_BUFFER_SIZE];
+#define DEBUG_STRING_SIZE 1024
+ gsize dbgs = DEBUG_STRING_SIZE;
+ char debug_string[DEBUG_STRING_SIZE];
+ char *dbgp;
if (ExceptionInfo == NULL ||
ExceptionInfo->ExceptionRecord == NULL ||
- IsDebuggerPresent ())
+ IsDebuggerPresent () ||
+ debugger[0] == 0)
return EXCEPTION_CONTINUE_SEARCH;
er = ExceptionInfo->ExceptionRecord;
@@ -1097,102 +1126,22 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
case EXCEPTION_ILLEGAL_INSTRUCTION:
break;
default:
- catch_list = g_getenv ("G_VEH_CATCH");
+ for (i = 0; i < number_of_exceptions_to_catch; i++)
+ if (exceptions_to_catch[i] == er->ExceptionCode)
+ break;
- while (!catch &&
- catch_list != NULL &&
- catch_list[0] != 0)
- {
- unsigned long catch_code;
- char *end;
- errno = 0;
- catch_code = strtoul (catch_list, &end, 16);
- if (errno != NO_ERROR)
- break;
- catch_list = end;
- if (catch_list != NULL && catch_list[0] == ',')
- catch_list++;
- if (catch_code == er->ExceptionCode)
- catch = TRUE;
- }
-
- if (catch)
- break;
+ if (i == number_of_exceptions_to_catch)
+ return EXCEPTION_CONTINUE_SEARCH;
- return EXCEPTION_CONTINUE_SEARCH;
- }
-
- fprintf_s (stderr,
- "Exception code=0x%lx flags=0x%lx at 0x%p",
- er->ExceptionCode,
- er->ExceptionFlags,
- er->ExceptionAddress);
-
- switch (er->ExceptionCode)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- fprintf_s (stderr,
- ". Access violation - attempting to %s at address 0x%p\n",
- er->ExceptionInformation[0] == 0 ? "read data" :
- er->ExceptionInformation[0] == 1 ? "write data" :
- er->ExceptionInformation[0] == 8 ? "execute data" :
- "do something bad",
- (void *) er->ExceptionInformation[1]);
- break;
- case EXCEPTION_IN_PAGE_ERROR:
- fprintf_s (stderr,
- ". Page access violation - attempting to %s at address 0x%p with status %Ix\n",
- er->ExceptionInformation[0] == 0 ? "read from an inaccessible page" :
- er->ExceptionInformation[0] == 1 ? "write to an inaccessible page" :
- er->ExceptionInformation[0] == 8 ? "execute data in page" :
- "do something bad with a page",
- (void *) er->ExceptionInformation[1],
- er->ExceptionInformation[2]);
- break;
- default:
- fprintf_s (stderr, "\n");
break;
}
- fflush (stderr);
-
- debugger_env = g_getenv ("G_DEBUGGER");
-
- if (debugger_env == NULL)
- return EXCEPTION_CONTINUE_SEARCH;
-
- /* Create an inheritable event */
memset (&si, 0, sizeof (si));
memset (&pi, 0, sizeof (pi));
- memset (&sa, 0, sizeof (sa));
si.cb = sizeof (si);
- sa.nLength = sizeof (sa);
- sa.bInheritHandle = TRUE;
- event = CreateEvent (&sa, FALSE, FALSE, NULL);
-
- /* Put process ID and event handle into debugger commandline */
- if (!_g_win32_subst_pid_and_event (debugger, G_N_ELEMENTS (debugger),
- debugger_env, GetCurrentProcessId (),
- (guintptr) event))
- {
- CloseHandle (event);
- return EXCEPTION_CONTINUE_SEARCH;
- }
- debugger[MAX_PATH] = '\0';
-
- debugger_utf16 = g_utf8_to_utf16 (debugger, -1, NULL, NULL, NULL);
/* Run the debugger */
- if (0 != CreateProcessW (NULL,
- debugger_utf16,
- NULL,
- NULL,
- TRUE,
- g_getenv ("G_DEBUGGER_OLD_CONSOLE") != NULL ? 0 : CREATE_NEW_CONSOLE,
- NULL,
- NULL,
- &si,
- &pi))
+ if (0 != CreateProcessW (NULL, debugger, NULL, NULL, TRUE, debugger_spawn_flags, NULL, NULL, &si, &pi))
{
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
@@ -1202,12 +1151,66 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
* up forever in case the debugger does not support
* event signalling.
*/
- WaitForSingleObject (event, 60000);
- }
-
- g_free (debugger_utf16);
+ WaitForSingleObject (debugger_wakeup_event, 60000);
+
+ dbgp = &debug_string[0];
+
+ dbgp = copy_chars (dbgp, &dbgs, "Exception code=0x");
+ itoa_buffer[0] = 0;
+ _ui64toa_s (er->ExceptionCode, itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+ dbgp = copy_chars (dbgp, &dbgs, " flags=0x");
+ itoa_buffer[0] = 0;
+ _ui64toa_s (er->ExceptionFlags, itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+ dbgp = copy_chars (dbgp, &dbgs, " at 0x");
+ itoa_buffer[0] = 0;
+ _ui64toa_s ((guintptr) er->ExceptionAddress, itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+
+ switch (er->ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ dbgp = copy_chars (dbgp, &dbgs, ". Access violation - attempting to ");
+ if (er->ExceptionInformation[0] == 0)
+ dbgp = copy_chars (dbgp, &dbgs, "read data");
+ else if (er->ExceptionInformation[0] == 1)
+ dbgp = copy_chars (dbgp, &dbgs, "write data");
+ else if (er->ExceptionInformation[0] == 8)
+ dbgp = copy_chars (dbgp, &dbgs, "execute data");
+ else
+ dbgp = copy_chars (dbgp, &dbgs, "do something bad");
+ dbgp = copy_chars (dbgp, &dbgs, " at address 0x");
+ itoa_buffer[0] = 0;
+ _ui64toa_s (er->ExceptionInformation[1], itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+ break;
+ case EXCEPTION_IN_PAGE_ERROR:
+ dbgp = copy_chars (dbgp, &dbgs, ". Page access violation - attempting to ");
+ if (er->ExceptionInformation[0] == 0)
+ dbgp = copy_chars (dbgp, &dbgs, "read from an inaccessible page");
+ else if (er->ExceptionInformation[0] == 1)
+ dbgp = copy_chars (dbgp, &dbgs, "write to an inaccessible page");
+ else if (er->ExceptionInformation[0] == 8)
+ dbgp = copy_chars (dbgp, &dbgs, "execute data in page");
+ else
+ dbgp = copy_chars (dbgp, &dbgs, "do something bad with a page");
+ dbgp = copy_chars (dbgp, &dbgs, " at address 0x");
+ itoa_buffer[0] = 0;
+ _ui64toa_s (er->ExceptionInformation[1], itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+ dbgp = copy_chars (dbgp, &dbgs, " with status ");
+ itoa_buffer[0] = 0;
+ _ui64toa_s (er->ExceptionInformation[2], itoa_buffer, ITOA_BUFFER_SIZE, 16);
+ dbgp = copy_chars (dbgp, &dbgs, itoa_buffer);
+ break;
+ default:
+ break;
+ }
- CloseHandle (event);
+ dbgp = copy_chars (dbgp, &dbgs, "\n");
+ OutputDebugStringA (debug_string);
+ }
/* Now the debugger is present, and we can try
* resuming execution, re-triggering the exception,
@@ -1219,20 +1222,88 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
return EXCEPTION_CONTINUE_SEARCH;
}
+static gsize
+parse_catch_list (const wchar_t *catch_buffer,
+ DWORD *exceptions,
+ gsize num_exceptions)
+{
+ const wchar_t *catch_list = catch_buffer;
+ gsize result = 0;
+ gsize i = 0;
+
+ while (catch_list != NULL &&
+ catch_list[0] != 0)
+ {
+ unsigned long catch_code;
+ wchar_t *end;
+ errno = 0;
+ catch_code = wcstoul (catch_list, &end, 16);
+ if (errno != NO_ERROR)
+ break;
+ catch_list = end;
+ if (catch_list != NULL && catch_list[0] == L',')
+ catch_list++;
+ if (exceptions && i < num_exceptions)
+ exceptions[i++] = catch_code;
+ }
+
+ return result;
+}
+
void
g_crash_handler_win32_init (void)
{
+ wchar_t debugger_env[DEBUGGER_BUFFER_SIZE];
+#define CATCH_BUFFER_SIZE 1024
+ wchar_t catch_buffer[CATCH_BUFFER_SIZE];
+ SECURITY_ATTRIBUTES sa;
+
if (WinVEH_handle != NULL)
return;
/* Do not register an exception handler if we're not supposed to catch any
* exceptions. Exception handlers are considered dangerous to use, and can
* break advanced exception handling such as in CLRs like C# or other managed
- * code. See: https://blogs.msdn.microsoft.com/jmstall/2006/05/24/beware-of-the-vectored-exception-handler-and-managed-code/
+ * code. See: http://www.windows-tech.info/13/785f590867bd6316.php
*/
- if (g_getenv ("G_DEBUGGER") == NULL && g_getenv("G_VEH_CATCH") == NULL)
+ debugger_env[0] = 0;
+ if (!GetEnvironmentVariableW (L"G_DEBUGGER", debugger_env, DEBUGGER_BUFFER_SIZE))
return;
+ /* Create an inheritable event */
+ memset (&sa, 0, sizeof (sa));
+ sa.nLength = sizeof (sa);
+ sa.bInheritHandle = TRUE;
+ debugger_wakeup_event = CreateEvent (&sa, FALSE, FALSE, NULL);
+
+ /* Put process ID and event handle into debugger commandline */
+ if (!_g_win32_subst_pid_and_event_w (debugger, G_N_ELEMENTS (debugger),
+ debugger_env, GetCurrentProcessId (),
+ (guintptr) debugger_wakeup_event))
+ {
+ CloseHandle (debugger_wakeup_event);
+ debugger_wakeup_event = 0;
+ debugger[0] = 0;
+ return;
+ }
+ debugger[MAX_PATH] = L'\0';
+
+ catch_buffer[0] = 0;
+ if (GetEnvironmentVariableW (L"G_VEH_CATCH", catch_buffer, CATCH_BUFFER_SIZE))
+ {
+ number_of_exceptions_to_catch = parse_catch_list (catch_buffer, NULL, 0);
+ if (number_of_exceptions_to_catch > 0)
+ {
+ exceptions_to_catch = g_new0 (DWORD, number_of_exceptions_to_catch);
+ parse_catch_list (catch_buffer, exceptions_to_catch, number_of_exceptions_to_catch);
+ }
+ }
+
+ if (GetEnvironmentVariableW (L"G_DEBUGGER_OLD_CONSOLE", (wchar_t *) &debugger_spawn_flags, 1))
+ debugger_spawn_flags = 0;
+ else
+ debugger_spawn_flags = CREATE_NEW_CONSOLE;
+
WinVEH_handle = AddVectoredExceptionHandler (0, &g_win32_veh_handler);
}
diff --git a/glib/meson.build b/glib/meson.build
index 8c18e6de4..93600b29e 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -3,9 +3,6 @@ configure_file(input : 'glibconfig.h.in', output : 'glibconfig.h',
configuration : glibconfig_conf)
subdir('libcharset')
-if not use_system_pcre
- subdir('pcre')
-endif
# libsysprof-capture support
libsysprof_capture_dep = dependency('sysprof-capture-4', version: '>= 3.38.0',
@@ -23,7 +20,7 @@ libsysprof_capture_dep = dependency('sysprof-capture-4', version: '>= 3.38.0',
)
glib_conf.set('HAVE_SYSPROF', libsysprof_capture_dep.found())
-# TODO: gnulib_objects, pcre_objects and pcre_deps are a workaround for
+# TODO: gnulib_objects is a workaround for
# <https://github.com/mesonbuild/meson/issues/3934> and
# <https://github.com/mesonbuild/meson/issues/3937>. When we can depend
# on a meson version where those are fixed, revert the commit that
@@ -142,6 +139,7 @@ install_headers(glib_deprecated_headers, subdir : 'glib-2.0/glib/deprecated')
glib_sub_headers = files(
'glib-autocleanups.h',
+ 'glib-typeof.h',
'galloca.h',
'garray.h',
'gasyncqueue.h',
@@ -357,19 +355,11 @@ if use_pcre_static_flag
pcre_static_args = ['-DPCRE_STATIC']
endif
-if use_system_pcre
- pcre_deps = [pcre]
- pcre_objects = []
-else
- pcre_deps = []
- pcre_objects = [libpcre.extract_all_objects()]
-endif
-
glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args
libglib = library('glib-2.0',
glib_dtrace_obj, glib_dtrace_hdr,
sources : [deprecated_sources, glib_sources],
- objects : [charset_lib.extract_all_objects()] + gnulib_objects + pcre_objects,
+ objects : [charset_lib.extract_all_objects()] + gnulib_objects,
version : library_version,
soversion : soversion,
darwin_versions : darwin_versions,
@@ -377,7 +367,7 @@ libglib = library('glib-2.0',
# intl.lib is not compatible with SAFESEH
link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
include_directories : configinc,
- dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
+ dependencies : [pcre, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
c_args : glib_c_args,
objc_args : glib_c_args,
)
diff --git a/glib/pcre/COPYING b/glib/pcre/COPYING
deleted file mode 100644
index 58eed01b6..000000000
--- a/glib/pcre/COPYING
+++ /dev/null
@@ -1,5 +0,0 @@
-PCRE LICENCE
-
-Please see the file LICENCE in the PCRE distribution for licensing details.
-
-End
diff --git a/glib/pcre/meson.build b/glib/pcre/meson.build
deleted file mode 100644
index 5152ecd60..000000000
--- a/glib/pcre/meson.build
+++ /dev/null
@@ -1,50 +0,0 @@
-pcre_sources = [
- 'pcre_byte_order.c',
- 'pcre_chartables.c',
- 'pcre_compile.c',
- 'pcre_config.c',
- 'pcre_dfa_exec.c',
- 'pcre_exec.c',
- 'pcre_fullinfo.c',
- 'pcre_get.c',
- 'pcre_globals.c',
- 'pcre_jit_compile.c',
- 'pcre_newline.c',
- 'pcre_ord2utf8.c',
- 'pcre_string_utils.c',
- 'pcre_study.c',
- 'pcre_tables.c',
- 'pcre_valid_utf8.c',
- 'pcre_version.c',
- 'pcre_xclass.c',
- 'pcre.h',
- 'pcre_internal.h',
- 'ucp.h',
-]
-
-libpcre = static_library('pcre',
- sources : [pcre_sources],
- include_directories : [configinc, glibinc],
- pic : true,
- c_args : [
- '-DG_LOG_DOMAIN="GLib-GRegex"',
- '-DHAVE_MEMMOVE',
- '-DSUPPORT_UCP',
- '-DSUPPORT_UTF',
- '-DSUPPORT_UTF8',
- '-DNEWLINE=-1',
- '-DMATCH_LIMIT=10000000',
- '-DMATCH_LIMIT_RECURSION=8192',
- '-DMAX_NAME_SIZE=32',
- '-DMAX_NAME_COUNT=10000',
- '-DMAX_DUPLENGTH=30000',
- '-DLINK_SIZE=2',
- '-DPOSIX_MALLOC_THRESHOLD=10',
- '-DPCRE_STATIC',
- '-UBSR_ANYCRLF',
- '-UEBCDIC',
- '-DGLIB_COMPILATION'
- ] + glib_hidden_visibility_args
-)
-
-pcre = declare_dependency(link_with : libpcre)
diff --git a/glib/pcre/pcre.h b/glib/pcre/pcre.h
deleted file mode 100644
index b71ead37a..000000000
--- a/glib/pcre/pcre.h
+++ /dev/null
@@ -1,507 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This is the public header file for the PCRE library, to be #included by
-applications that call the PCRE functions.
-
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef _PCRE_H
-#define _PCRE_H
-
-/* The current PCRE version information. */
-
-#define PCRE_MAJOR 8
-#define PCRE_MINOR 31
-#define PCRE_PRERELEASE
-#define PCRE_DATE 2012-07-06
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE, the appropriate
-export setting is defined in pcre_internal.h, which includes this file. So we
-don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC)
-# ifndef PCRE_EXP_DECL
-# define PCRE_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN __declspec(dllimport)
-# endif
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-#endif
-
-#ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN
-# endif
-#endif
-
-/* Have to include stdlib.h in order to ensure that size_t is defined;
-it is needed here for malloc. */
-
-#include <stdlib.h>
-
-/* Allow for C++ users */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Options. Some are compile-time only, some are run-time only, and some are
-both, so we keep them all distinct. However, almost all the bits in the options
-word are now used. In the long run, we may have to re-use some of the
-compile-time only bits for runtime options, or vice versa. In the comments
-below, "compile", "exec", and "DFA exec" mean that the option is permitted to
-be set for those functions; "used in" means that an option may be set only for
-compile, but is subsequently referenced in exec and/or DFA exec. Any of the
-compile-time options may be inspected during studying (and therefore JIT
-compiling). */
-
-#define PCRE_CASELESS 0x00000001 /* Compile */
-#define PCRE_MULTILINE 0x00000002 /* Compile */
-#define PCRE_DOTALL 0x00000004 /* Compile */
-#define PCRE_EXTENDED 0x00000008 /* Compile */
-#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
-#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
-#define PCRE_EXTRA 0x00000040 /* Compile */
-#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
-#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
-#define PCRE_UNGREEDY 0x00000200 /* Compile */
-#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
-/* The next two are also used in exec and DFA exec */
-#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
-#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
-#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
-/* The next two are also used in exec and DFA exec */
-#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
-#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
-#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
-#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
-#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
-#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
-#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
-#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
-#define PCRE_DUPNAMES 0x00080000 /* Compile */
-#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
-#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
-#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */
-#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */
-#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
-#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
-#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
-#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
-#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
-#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
-#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
-#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
-
-/* Exec-time and get/set-time error codes */
-
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
-#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
-#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
-#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-#define PCRE_ERROR_BADOFFSET (-24)
-#define PCRE_ERROR_SHORTUTF8 (-25)
-#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
-#define PCRE_ERROR_RECURSELOOP (-26)
-#define PCRE_ERROR_JIT_STACKLIMIT (-27)
-#define PCRE_ERROR_BADMODE (-28)
-#define PCRE_ERROR_BADENDIANNESS (-29)
-#define PCRE_ERROR_DFA_BADRESTART (-30)
-
-/* Specific error codes for UTF-8 validity checks */
-
-#define PCRE_UTF8_ERR0 0
-#define PCRE_UTF8_ERR1 1
-#define PCRE_UTF8_ERR2 2
-#define PCRE_UTF8_ERR3 3
-#define PCRE_UTF8_ERR4 4
-#define PCRE_UTF8_ERR5 5
-#define PCRE_UTF8_ERR6 6
-#define PCRE_UTF8_ERR7 7
-#define PCRE_UTF8_ERR8 8
-#define PCRE_UTF8_ERR9 9
-#define PCRE_UTF8_ERR10 10
-#define PCRE_UTF8_ERR11 11
-#define PCRE_UTF8_ERR12 12
-#define PCRE_UTF8_ERR13 13
-#define PCRE_UTF8_ERR14 14
-#define PCRE_UTF8_ERR15 15
-#define PCRE_UTF8_ERR16 16
-#define PCRE_UTF8_ERR17 17
-#define PCRE_UTF8_ERR18 18
-#define PCRE_UTF8_ERR19 19
-#define PCRE_UTF8_ERR20 20
-#define PCRE_UTF8_ERR21 21
-
-/* Specific error codes for UTF-16 validity checks */
-
-#define PCRE_UTF16_ERR0 0
-#define PCRE_UTF16_ERR1 1
-#define PCRE_UTF16_ERR2 2
-#define PCRE_UTF16_ERR3 3
-#define PCRE_UTF16_ERR4 4
-
-/* Request types for pcre_fullinfo() */
-
-#define PCRE_INFO_OPTIONS 0
-#define PCRE_INFO_SIZE 1
-#define PCRE_INFO_CAPTURECOUNT 2
-#define PCRE_INFO_BACKREFMAX 3
-#define PCRE_INFO_FIRSTBYTE 4
-#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
-#define PCRE_INFO_FIRSTTABLE 5
-#define PCRE_INFO_LASTLITERAL 6
-#define PCRE_INFO_NAMEENTRYSIZE 7
-#define PCRE_INFO_NAMECOUNT 8
-#define PCRE_INFO_NAMETABLE 9
-#define PCRE_INFO_STUDYSIZE 10
-#define PCRE_INFO_DEFAULT_TABLES 11
-#define PCRE_INFO_OKPARTIAL 12
-#define PCRE_INFO_JCHANGED 13
-#define PCRE_INFO_HASCRORLF 14
-#define PCRE_INFO_MINLENGTH 15
-#define PCRE_INFO_JIT 16
-#define PCRE_INFO_JITSIZE 17
-#define PCRE_INFO_MAXLOOKBEHIND 18
-
-/* Request types for pcre_config(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_CONFIG_UTF8 0
-#define PCRE_CONFIG_NEWLINE 1
-#define PCRE_CONFIG_LINK_SIZE 2
-#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
-#define PCRE_CONFIG_MATCH_LIMIT 4
-#define PCRE_CONFIG_STACKRECURSE 5
-#define PCRE_CONFIG_UNICODE_PROPERTIES 6
-#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
-#define PCRE_CONFIG_BSR 8
-#define PCRE_CONFIG_JIT 9
-#define PCRE_CONFIG_UTF16 10
-#define PCRE_CONFIG_JITTARGET 11
-
-/* Request types for pcre_study(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_STUDY_JIT_COMPILE 0x0001
-#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
-#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
-
-/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
-these bits, just add new ones on the end, in order to remain compatible. */
-
-#define PCRE_EXTRA_STUDY_DATA 0x0001
-#define PCRE_EXTRA_MATCH_LIMIT 0x0002
-#define PCRE_EXTRA_CALLOUT_DATA 0x0004
-#define PCRE_EXTRA_TABLES 0x0008
-#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
-#define PCRE_EXTRA_MARK 0x0020
-#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
-
-/* Types */
-
-struct real_pcre; /* declaration; the definition is private */
-typedef struct real_pcre pcre;
-
-struct real_pcre16; /* declaration; the definition is private */
-typedef struct real_pcre16 pcre16;
-
-struct real_pcre_jit_stack; /* declaration; the definition is private */
-typedef struct real_pcre_jit_stack pcre_jit_stack;
-
-struct real_pcre16_jit_stack; /* declaration; the definition is private */
-typedef struct real_pcre16_jit_stack pcre16_jit_stack;
-
-/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
-a 16 bit wide signed data type. Otherwise it can be a dummy data type since
-pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
-#ifndef PCRE_UCHAR16
-#define PCRE_UCHAR16 unsigned short
-#endif
-
-#ifndef PCRE_SPTR16
-#define PCRE_SPTR16 const PCRE_UCHAR16 *
-#endif
-
-/* When PCRE is compiled as a C++ library, the subject pointer type can be
-replaced with a custom type. For conventional use, the public interface is a
-const char *. */
-
-#ifndef PCRE_SPTR
-#define PCRE_SPTR const char *
-#endif
-
-/* The structure for passing additional data to pcre_exec(). This is defined in
-such as way as to be extensible. Always add new fields at the end, in order to
-remain compatible. */
-
-typedef struct pcre_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
- unsigned char **mark; /* For passing back a mark pointer */
- void *executable_jit; /* Contains a pointer to a compiled jit code */
-} pcre_extra;
-
-/* Same structure as above, but with 16 bit char pointers. */
-
-typedef struct pcre16_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
- PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
- void *executable_jit; /* Contains a pointer to a compiled jit code */
-} pcre16_extra;
-
-/* The structure for passing out data via the pcre_callout_function. We use a
-structure so that new fields can be added on the end in future versions,
-without changing the API of the function, thereby allowing old clients to work
-without modification. */
-
-typedef struct pcre_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------- Added for Version 2 -------------------------- */
- const unsigned char *mark; /* Pointer to current mark or NULL */
- /* ------------------------------------------------------------------ */
-} pcre_callout_block;
-
-/* Same structure as above, but with 16 bit char pointers. */
-
-typedef struct pcre16_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR16 subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------- Added for Version 2 -------------------------- */
- const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
- /* ------------------------------------------------------------------ */
-} pcre16_callout_block;
-
-/* Indirection for store get and free functions. These can be set to
-alternative malloc/free functions if required. Special ones are used in the
-non-recursive case for "frames". There is also an optional callout function
-that is triggered by the (?) regex item. For Virtual Pascal, these definitions
-have to take another form. */
-
-#ifndef VPCOMPAT
-PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_free)(void *);
-PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
-
-PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre16_free)(void *);
-PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
-#else /* VPCOMPAT */
-PCRE_EXP_DECL void *pcre_malloc(size_t);
-PCRE_EXP_DECL void pcre_free(void *);
-PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre_stack_free(void *);
-PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
-
-PCRE_EXP_DECL void *pcre16_malloc(size_t);
-PCRE_EXP_DECL void pcre16_free(void *);
-PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre16_stack_free(void *);
-PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
-#endif /* VPCOMPAT */
-
-/* User defined callback which provides a stack just before the match starts. */
-
-typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
-typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
-
-/* Exported PCRE functions */
-
-PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL int pcre_config(int, void *);
-PCRE_EXP_DECL int pcre16_config(int, void *);
-PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
- int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
- int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
- char *, int);
-PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
- PCRE_UCHAR16 *, int);
-PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
- const char *, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
- PCRE_SPTR16, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
- int, int, int, int *, int);
-PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
- PCRE_SPTR16, int, int, int, int *, int);
-PCRE_EXP_DECL void pcre_free_substring(const char *);
-PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
-PCRE_EXP_DECL void pcre_free_substring_list(const char **);
-PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
-PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
- int *, int, const char *, const char **);
-PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
- int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
-PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
-PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
-PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
- char **, char **);
-PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
- PCRE_UCHAR16 **, PCRE_UCHAR16 **);
-PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
- const char **);
-PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
- PCRE_SPTR16 *);
-PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
- const char ***);
-PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
- PCRE_SPTR16 **);
-PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
-PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
-PCRE_EXP_DECL int pcre_refcount(pcre *, int);
-PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
-PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
-PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
-PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
-PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
-PCRE_EXP_DECL const char *pcre_version(void);
-PCRE_EXP_DECL const char *pcre16_version(void);
-
-/* Utility functions for byte order swaps. */
-PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
- const unsigned char *);
-PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
- const unsigned char *);
-PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
- PCRE_SPTR16, int, int *, int);
-
-/* JIT compiler related functions. */
-
-PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
-PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
-PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
-PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
-PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
- pcre_jit_callback, void *);
-PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
- pcre16_jit_callback, void *);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* End of pcre.h */
diff --git a/glib/pcre/pcre_byte_order.c b/glib/pcre/pcre_byte_order.c
deleted file mode 100644
index 4f21433c1..000000000
--- a/glib/pcre/pcre_byte_order.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that tests a compiled pattern to
-see if it was compiled with the opposite endianness. If so, it uses an
-auxiliary local function to flip the appropriate bytes. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Swap byte functions *
-*************************************************/
-
-/* The following functions swap the bytes of a pcre_uint16
-and pcre_uint32 value.
-
-Arguments:
- value any number
-
-Returns: the byte swapped value
-*/
-
-static pcre_uint32
-swap_uint32(pcre_uint32 value)
-{
-return ((value & 0x000000ff) << 24) |
- ((value & 0x0000ff00) << 8) |
- ((value & 0x00ff0000) >> 8) |
- (value >> 24);
-}
-
-static pcre_uint16
-swap_uint16(pcre_uint16 value)
-{
-return (value >> 8) | (value << 8);
-}
-
-
-/*************************************************
-* Test for a byte-flipped compiled regex *
-*************************************************/
-
-/* This function swaps the bytes of a compiled pattern usually
-loaded form the disk. It also sets the tables pointer, which
-is likely an invalid pointer after reload.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- tables points to the character tables or NULL
-
-Returns: 0 if the swap is successful, negative on error
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
- pcre_extra *extra_data, const unsigned char *tables)
-#else
-PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
- pcre16_extra *extra_data, const unsigned char *tables)
-#endif
-{
-REAL_PCRE *re = (REAL_PCRE *)argument_re;
-pcre_study_data *study;
-#ifndef COMPILE_PCRE8
-pcre_uchar *ptr;
-int length;
-#ifdef SUPPORT_UTF
-BOOL utf;
-BOOL utf16_char;
-#endif /* SUPPORT_UTF */
-#endif /* !COMPILE_PCRE8 */
-
-if (re == NULL) return PCRE_ERROR_NULL;
-if (re->magic_number == MAGIC_NUMBER)
- {
- if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
- re->tables = tables;
- return 0;
- }
-
-if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
-if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-re->magic_number = MAGIC_NUMBER;
-re->size = swap_uint32(re->size);
-re->options = swap_uint32(re->options);
-re->flags = swap_uint16(re->flags);
-re->top_bracket = swap_uint16(re->top_bracket);
-re->top_backref = swap_uint16(re->top_backref);
-re->first_char = swap_uint16(re->first_char);
-re->req_char = swap_uint16(re->req_char);
-re->name_table_offset = swap_uint16(re->name_table_offset);
-re->name_entry_size = swap_uint16(re->name_entry_size);
-re->name_count = swap_uint16(re->name_count);
-re->ref_count = swap_uint16(re->ref_count);
-re->tables = tables;
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
- {
- study = (pcre_study_data *)extra_data->study_data;
- study->size = swap_uint32(study->size);
- study->flags = swap_uint32(study->flags);
- study->minlength = swap_uint32(study->minlength);
- }
-
-#ifndef COMPILE_PCRE8
-ptr = (pcre_uchar *)re + re->name_table_offset;
-length = re->name_count * re->name_entry_size;
-#ifdef SUPPORT_UTF
-utf = (re->options & PCRE_UTF16) != 0;
-utf16_char = FALSE;
-#endif
-
-while(TRUE)
- {
- /* Swap previous characters. */
- while (length-- > 0)
- {
- *ptr = swap_uint16(*ptr);
- ptr++;
- }
-#ifdef SUPPORT_UTF
- if (utf16_char)
- {
- if (HAS_EXTRALEN(ptr[-1]))
- {
- /* We know that there is only one extra character in UTF-16. */
- *ptr = swap_uint16(*ptr);
- ptr++;
- }
- }
- utf16_char = FALSE;
-#endif /* SUPPORT_UTF */
-
- /* Get next opcode. */
- length = 0;
- *ptr = swap_uint16(*ptr);
- switch (*ptr)
- {
- case OP_END:
- return 0;
-
-#ifdef SUPPORT_UTF
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- if (utf) utf16_char = TRUE;
-#endif
- /* Fall through. */
-
- default:
- length = PRIV(OP_lengths)[*ptr] - 1;
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
- /* Skip the character bit map. */
- ptr += 32/sizeof(pcre_uchar);
- length = 0;
- break;
-
- case OP_XCLASS:
- /* Reverse the size of the XCLASS instance. */
- ptr++;
- *ptr = swap_uint16(*ptr);
- if (LINK_SIZE > 1)
- {
- /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
- ptr++;
- *ptr = swap_uint16(*ptr);
- }
- ptr++;
- length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
- *ptr = swap_uint16(*ptr);
- if ((*ptr & XCL_MAP) != 0)
- {
- /* Skip the character bit map. */
- ptr += 32/sizeof(pcre_uchar);
- length -= 32/sizeof(pcre_uchar);
- }
- break;
- }
- ptr++;
- }
-/* Control should never reach here in 16 bit mode. */
-#endif /* !COMPILE_PCRE8 */
-
-return 0;
-}
-
-/* End of pcre_byte_order.c */
diff --git a/glib/pcre/pcre_chartables.c b/glib/pcre/pcre_chartables.c
deleted file mode 100644
index 293b16b32..000000000
--- a/glib/pcre/pcre_chartables.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This file contains character tables that are used when no external tables
-are passed to PCRE by the application that calls it. The tables are used only
-for characters whose code values are less than 256.
-
-This is a default version of the tables that assumes ASCII encoding. A program
-called dftables (which is distributed with PCRE) can be used to build
-alternative versions of this file. This is necessary if you are running in an
-EBCDIC environment, or if you want to default to a different encoding, for
-example ISO-8859-1. When dftables is run, it creates these tables in the
-current locale. If PCRE is configured with --enable-rebuild-chartables, this
-happens automatically.
-
-The following #includes are present because without them gcc 4.x may remove the
-array definition from the final binary if PCRE is built into a static library
-and dead code stripping is activated. This leads to link errors. Pulling in the
-header ensures that the array gets flagged as "someone outside this compilation
-unit might reference this" and so it will always be supplied to the linker. */
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-const pcre_uint8 PRIV(default_tables)[] = {
-
-/* This table is a lower casing table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes. Each map is 32
-bytes long and the bits run from the least significant end of each byte. The
-classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph, print, punct, and cntrl. Other classes are built from combinations. */
-
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
- 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
- 0x01 white space character
- 0x02 letter
- 0x04 decimal digit
- 0x08 hexadecimal digit
- 0x10 alphanumeric or '_'
- 0x80 regular expression metacharacter or binary zero
-*/
-
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
- 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of pcre_chartables.c */
diff --git a/glib/pcre/pcre_compile.c b/glib/pcre/pcre_compile.c
deleted file mode 100644
index 12e09c4ef..000000000
--- a/glib/pcre/pcre_compile.c
+++ /dev/null
@@ -1,8213 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_compile(), along with
-supporting internal functions that are not used by other modules. */
-
-
-#include "config.h"
-
-#define NLBLOCK cd /* Block containing newline information */
-#define PSSTART start_pattern /* Field containing processed string start */
-#define PSEND end_pattern /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-#ifdef GLIB_COMPILATION
-#include "gstrfuncs.h"
-#else
-#include <glib.h>
-#endif
-
-/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which
-is also used by pcretest. PCRE_DEBUG is not defined when building a production
-library. We do not need to select pcre16_printint.c specially, because the
-COMPILE_PCREx macro will already be appropriately set. */
-
-#ifdef PCRE_DEBUG
-/* pcre_printint.c should not include any headers */
-#define PCRE_INCLUDED
-#include "pcre_printint.c"
-#undef PCRE_INCLUDED
-#endif
-
-
-/* Macro for setting individual bits in class bitmaps. */
-
-#define SETBIT(a,b) a[b/8] |= (1 << (b%8))
-
-/* Maximum length value to check against when making sure that the integer that
-holds the compiled pattern length does not overflow. We make it a bit less than
-INT_MAX to allow for adding in group terminating bytes, so that we don't have
-to check them every time. */
-
-#define OFLOW_MAX (INT_MAX - 20)
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* This value specifies the size of stack workspace that is used during the
-first pre-compile phase that determines how much memory is required. The regex
-is partly compiled into this space, but the compiled parts are discarded as
-soon as they can be, so that hopefully there will never be an overrun. The code
-does, however, check for an overrun. The largest amount I've seen used is 218,
-so this number is very generous.
-
-The same workspace is used during the second, actual compile phase for
-remembering forward references to groups so that they can be filled in at the
-end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
-is 4 there is plenty of room for most patterns. However, the memory can get
-filled up by repetitions of forward references, for example patterns like
-/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so
-that the workspace is expanded using malloc() in this situation. The value
-below is therefore a minimum, and we put a maximum on it for safety. The
-minimum is now also defined in terms of LINK_SIZE so that the use of malloc()
-kicks in at the same number of forward references in all cases. */
-
-#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
-#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
-
-/* The overrun tests check for a slightly smaller size so that they detect the
-overrun before it actually does run off the end of the data block. */
-
-#define WORK_SIZE_SAFETY_MARGIN (100)
-
-/* Private flags added to firstchar and reqchar. */
-
-#define REQ_CASELESS 0x10000000l /* Indicates caselessness */
-#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */
-
-/* Repeated character flags. */
-
-#define UTF_LENGTH 0x10000000l /* The char contains its length. */
-
-/* Table for handling escaped characters in the range '0'-'z'. Positive returns
-are simple data values; negative values are for special things like \d and so
-on. Zero means further processing is needed (for things like \x), or the escape
-is invalid. */
-
-#ifndef EBCDIC
-
-/* This is the "normal" table for ASCII systems or for EBCDIC systems running
-in UTF-8 mode. */
-
-static const short int escapes[] = {
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- CHAR_COLON, CHAR_SEMICOLON,
- CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
- CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
- CHAR_COMMERCIAL_AT, -ESC_A,
- -ESC_B, -ESC_C,
- -ESC_D, -ESC_E,
- 0, -ESC_G,
- -ESC_H, 0,
- 0, -ESC_K,
- 0, 0,
- -ESC_N, 0,
- -ESC_P, -ESC_Q,
- -ESC_R, -ESC_S,
- 0, 0,
- -ESC_V, -ESC_W,
- -ESC_X, 0,
- -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
- CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
- CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
- CHAR_GRAVE_ACCENT, 7,
- -ESC_b, 0,
- -ESC_d, ESC_e,
- ESC_f, 0,
- -ESC_h, 0,
- 0, -ESC_k,
- 0, 0,
- ESC_n, 0,
- -ESC_p, 0,
- ESC_r, -ESC_s,
- ESC_tee, 0,
- -ESC_v, -ESC_w,
- 0, 0,
- -ESC_z
-};
-
-#else
-
-/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
-
-static const short int escapes[] = {
-/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
-/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
-/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
-/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
-/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
-/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
-/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
-/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
-/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
-/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
-/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
-/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
-/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
-/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
-/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
-/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P,
-/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
-/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
-/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
-/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
-};
-#endif
-
-
-/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
-searched linearly. Put all the names into a single string, in order to reduce
-the number of relocations when a shared library is dynamically linked. The
-string is built from string macros so that it works in UTF-8 mode on EBCDIC
-platforms. */
-
-typedef struct verbitem {
- int len; /* Length of verb name */
- int op; /* Op when no arg, or -1 if arg mandatory */
- int op_arg; /* Op when arg present, or -1 if not allowed */
-} verbitem;
-
-static const char verbnames[] =
- "\0" /* Empty name is a shorthand for MARK */
- STRING_MARK0
- STRING_ACCEPT0
- STRING_COMMIT0
- STRING_F0
- STRING_FAIL0
- STRING_PRUNE0
- STRING_SKIP0
- STRING_THEN;
-
-static const verbitem verbs[] = {
- { 0, -1, OP_MARK },
- { 4, -1, OP_MARK },
- { 6, OP_ACCEPT, -1 },
- { 6, OP_COMMIT, -1 },
- { 1, OP_FAIL, -1 },
- { 4, OP_FAIL, -1 },
- { 5, OP_PRUNE, OP_PRUNE_ARG },
- { 4, OP_SKIP, OP_SKIP_ARG },
- { 4, OP_THEN, OP_THEN_ARG }
-};
-
-static const int verbcount = sizeof(verbs)/sizeof(verbitem);
-
-
-/* Tables of names of POSIX character classes and their lengths. The names are
-now all in a single string, to reduce the number of relocations when a shared
-library is dynamically loaded. The list of lengths is terminated by a zero
-length entry. The first three must be alpha, lower, upper, as this is assumed
-for handling case independence. */
-
-static const char posix_names[] =
- STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
- STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
- STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
- STRING_word0 STRING_xdigit;
-
-static const pcre_uint8 posix_name_lengths[] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
-
-/* Table of class bit maps for each POSIX class. Each class is formed from a
-base map, with an optional addition or removal of another map. Then, for some
-classes, there is some additional tweaking: for [:blank:] the vertical space
-characters are removed, and for [:alpha:] and [:alnum:] the underscore
-character is removed. The triples in the table consist of the base map offset,
-second map offset or -1 if no second map, and a non-negative value for map
-addition or a negative value for map subtraction (if there are two maps). The
-absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
-remove vertical space characters, 2 => remove underscore. */
-
-static const int posix_class_maps[] = {
- cbit_word, cbit_digit, -2, /* alpha */
- cbit_lower, -1, 0, /* lower */
- cbit_upper, -1, 0, /* upper */
- cbit_word, -1, 2, /* alnum - word without underscore */
- cbit_print, cbit_cntrl, 0, /* ascii */
- cbit_space, -1, 1, /* blank - a GNU extension */
- cbit_cntrl, -1, 0, /* cntrl */
- cbit_digit, -1, 0, /* digit */
- cbit_graph, -1, 0, /* graph */
- cbit_print, -1, 0, /* print */
- cbit_punct, -1, 0, /* punct */
- cbit_space, -1, 0, /* space */
- cbit_word, -1, 0, /* word - a Perl extension */
- cbit_xdigit,-1, 0 /* xdigit */
-};
-
-/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class
-substitutes must be in the order of the names, defined above, and there are
-both positive and negative cases. NULL means no substitute. */
-
-#ifdef SUPPORT_UCP
-static const pcre_uchar string_PNd[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pNd[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXsp[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXsp[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXwd[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXwd[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-
-static const pcre_uchar *substitutes[] = {
- string_PNd, /* \D */
- string_pNd, /* \d */
- string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
- string_pXsp, /* \s */
- string_PXwd, /* \W */
- string_pXwd /* \w */
-};
-
-static const pcre_uchar string_pL[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pLl[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pLu[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXan[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_h[] = {
- CHAR_BACKSLASH, CHAR_h, '\0' };
-static const pcre_uchar string_pXps[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PL[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PLl[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PLu[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXan[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_H[] = {
- CHAR_BACKSLASH, CHAR_H, '\0' };
-static const pcre_uchar string_PXps[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-
-static const pcre_uchar *posix_substitutes[] = {
- string_pL, /* alpha */
- string_pLl, /* lower */
- string_pLu, /* upper */
- string_pXan, /* alnum */
- NULL, /* ascii */
- string_h, /* blank */
- NULL, /* cntrl */
- string_pNd, /* digit */
- NULL, /* graph */
- NULL, /* print */
- NULL, /* punct */
- string_pXps, /* space */ /* NOTE: Xps is POSIX space */
- string_pXwd, /* word */
- NULL, /* xdigit */
- /* Negated cases */
- string_PL, /* ^alpha */
- string_PLl, /* ^lower */
- string_PLu, /* ^upper */
- string_PXan, /* ^alnum */
- NULL, /* ^ascii */
- string_H, /* ^blank */
- NULL, /* ^cntrl */
- string_PNd, /* ^digit */
- NULL, /* ^graph */
- NULL, /* ^print */
- NULL, /* ^punct */
- string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
- string_PXwd, /* ^word */
- NULL /* ^xdigit */
-};
-#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
-#endif
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* The texts of compile-time error messages. These are "char *" because they
-are passed to the outside world. Do not ever re-use any error number, because
-they are documented. Always add a new error instead. Messages marked DEAD below
-are no longer used. This used to be a table of strings, but in order to reduce
-the number of relocations needed when a shared library is loaded dynamically,
-it is now one long string. We cannot use a table of offsets, because the
-lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
-simply count through to the one we want - this isn't a performance issue
-because these strings are used only when there is a compilation error.
-
-Each substring ends with \0 to insert a null character. This includes the final
-substring, so that the whole string ends with \0\0, which can be detected when
-counting through. */
-
-static const char error_texts[] =
- "no error\0"
- "\\ at end of pattern\0"
- "\\c at end of pattern\0"
- "unrecognized character follows \\\0"
- "numbers out of order in {} quantifier\0"
- /* 5 */
- "number too big in {} quantifier\0"
- "missing terminating ] for character class\0"
- "invalid escape sequence in character class\0"
- "range out of order in character class\0"
- "nothing to repeat\0"
- /* 10 */
- "operand of unlimited repeat could match the empty string\0" /** DEAD **/
- "internal error: unexpected repeat\0"
- "unrecognized character after (? or (?-\0"
- "POSIX named classes are supported only within a class\0"
- "missing )\0"
- /* 15 */
- "reference to non-existent subpattern\0"
- "erroffset passed as NULL\0"
- "unknown option bit(s) set\0"
- "missing ) after comment\0"
- "parentheses nested too deeply\0" /** DEAD **/
- /* 20 */
- "regular expression is too large\0"
- "failed to get memory\0"
- "unmatched parentheses\0"
- "internal error: code overflow\0"
- "unrecognized character after (?<\0"
- /* 25 */
- "lookbehind assertion is not fixed length\0"
- "malformed number or name after (?(\0"
- "conditional group contains more than two branches\0"
- "assertion expected after (?(\0"
- "(?R or (?[+-]digits must be followed by )\0"
- /* 30 */
- "unknown POSIX class name\0"
- "POSIX collating elements are not supported\0"
- "this version of PCRE is compiled without UTF support\0"
- "spare error\0" /** DEAD **/
- "character value in \\x{...} sequence is too large\0"
- /* 35 */
- "invalid condition (?(0)\0"
- "\\C not allowed in lookbehind assertion\0"
- "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
- "number after (?C is > 255\0"
- "closing ) for (?C expected\0"
- /* 40 */
- "recursive call could loop indefinitely\0"
- "unrecognized character after (?P\0"
- "syntax error in subpattern name (missing terminator)\0"
- "two named subpatterns have the same name\0"
- "invalid UTF-8 string\0"
- /* 45 */
- "support for \\P, \\p, and \\X has not been compiled\0"
- "malformed \\P or \\p sequence\0"
- "unknown property name after \\P or \\p\0"
- "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
- "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
- /* 50 */
- "repeated subpattern is too long\0" /** DEAD **/
- "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
- "internal error: overran compiling workspace\0"
- "internal error: previously-checked referenced subpattern not found\0"
- "DEFINE group contains more than one branch\0"
- /* 55 */
- "repeating a DEFINE group is not allowed\0" /** DEAD **/
- "inconsistent NEWLINE options\0"
- "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
- "a numbered reference must not be zero\0"
- "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
- /* 60 */
- "(*VERB) not recognized\0"
- "number is too big\0"
- "subpattern name expected\0"
- "digit expected after (?+\0"
- "] is an invalid data character in JavaScript compatibility mode\0"
- /* 65 */
- "different names for subpatterns of the same number are not allowed\0"
- "(*MARK) must have an argument\0"
- "this version of PCRE is not compiled with Unicode property support\0"
- "\\c must be followed by an ASCII character\0"
- "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
- /* 70 */
- "internal error: unknown opcode in find_fixedlength()\0"
- "\\N is not supported in a class\0"
- "too many forward references\0"
- "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
- "invalid UTF-16 string\0"
- /* 75 */
- "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
- "character value in \\u.... sequence is too large\0"
- ;
-
-/* Table to identify digits and hex digits. This is used when compiling
-patterns. Note that the tables in chartables are dependent on the locale, and
-may mark arbitrary characters as digits - but the PCRE compiling code expects
-to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
-a private table here. It costs 256 bytes, but it is a lot faster than doing
-character value tests (at least in some simple cases I timed), and in some
-applications one wants PCRE to compile efficiently as well as match
-efficiently.
-
-For convenience, we use the same bit definitions as in chartables:
-
- 0x04 decimal digit
- 0x08 hexadecimal digit
-
-Then we can use ctype_digit and ctype_xdigit in the code. */
-
-/* Using a simple comparison for decimal numbers rather than a memory read
-is much faster, and the resulting code is simpler (the compiler turns it
-into a subtraction and unsigned comparison). */
-
-#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
-
-#if 0
-#ifndef EBCDIC
-
-/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
-UTF-8 mode. */
-
-static const pcre_uint8 digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-#else
-
-/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
-
-static const pcre_uint8 digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-
-static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
- 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
- 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
- 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
- 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
- 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-#endif
-#endif /* 0 */
-
-/* Definition to allow mutual recursion */
-
-static BOOL
- compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int,
- int *, int *, branch_chain *, compile_data *, int *);
-
-
-
-/*************************************************
-* Find an error text *
-*************************************************/
-
-/* The error texts are now all in one long string, to save on relocations. As
-some of the text is of unknown length, we can't use a table of offsets.
-Instead, just count through the strings. This is not a performance issue
-because it happens only when there has been a compilation error.
-
-Argument: the error number
-Returns: pointer to the error string
-*/
-
-static const char *
-find_error_text(int n)
-{
-const char *s = error_texts;
-for (; n > 0; n--)
- {
- while (*s++ != 0) {};
- if (*s == 0) return "Error text not found (please report)";
- }
-return s;
-}
-
-
-/*************************************************
-* Expand the workspace *
-*************************************************/
-
-/* This function is called during the second compiling phase, if the number of
-forward references fills the existing workspace, which is originally a block on
-the stack. A larger block is obtained from malloc() unless the ultimate limit
-has been reached or the increase will be rather small.
-
-Argument: pointer to the compile data block
-Returns: 0 if all went well, else an error number
-*/
-
-static int
-expand_workspace(compile_data *cd)
-{
-pcre_uchar *newspace;
-int newsize = cd->workspace_size * 2;
-
-if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;
-if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
- newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
- return ERR72;
-
-newspace = (PUBL(malloc))(IN_UCHARS(newsize));
-if (newspace == NULL) return ERR21;
-memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
-cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
-if (cd->workspace_size > COMPILE_WORK_SIZE)
- (PUBL(free))((void *)cd->start_workspace);
-cd->start_workspace = newspace;
-cd->workspace_size = newsize;
-return 0;
-}
-
-
-
-/*************************************************
-* Check for counted repeat *
-*************************************************/
-
-/* This function is called when a '{' is encountered in a place where it might
-start a quantifier. It looks ahead to see if it really is a quantifier or not.
-It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
-where the ddds are digits.
-
-Arguments:
- p pointer to the first char after '{'
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_counted_repeat(const pcre_uchar *p)
-{
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (*p++ != CHAR_COMMA) return FALSE;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-
-return (*p == CHAR_RIGHT_CURLY_BRACKET);
-}
-
-
-
-/*************************************************
-* Handle escapes *
-*************************************************/
-
-/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \n, or a negative value which
-encodes one of the more complicated things such as \d. A backreference to group
-n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When
-UTF-8 is enabled, a positive value greater than 255 may be returned. On entry,
-ptr is pointing at the \. On exit, it is on the final character of the escape
-sequence.
-
-Arguments:
- ptrptr points to the pattern position pointer
- errorcodeptr points to the errorcode variable
- bracount number of previous extracting brackets
- options the options bits
- isclass TRUE if inside a character class
-
-Returns: zero or positive => a data character
- negative => a special escape sequence
- on error, errorcodeptr is set
-*/
-
-static int
-check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount,
- int options, BOOL isclass)
-{
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-const pcre_uchar *ptr = *ptrptr + 1;
-pcre_int32 c;
-int i;
-
-GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
-ptr--; /* Set pointer back to the last byte */
-
-/* If backslash is at the end of the pattern, it's an error. */
-
-if (c == 0) *errorcodeptr = ERR1;
-
-/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
-in a table. A non-zero result is something that can be returned immediately.
-Otherwise further processing may be required. */
-
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
-/* Not alphanumeric */
-else if (c < CHAR_0 || c > CHAR_z) {}
-else if ((i = escapes[c - CHAR_0]) != 0) c = i;
-
-#else /* EBCDIC coding */
-/* Not alphanumeric */
-else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {}
-else if ((i = escapes[c - 0x48]) != 0) c = i;
-#endif
-
-/* Escapes that need further processing, or are illegal. */
-
-else
- {
- const pcre_uchar *oldptr;
- BOOL braced, negated;
-
- switch (c)
- {
- /* A number of Perl escapes are not handled by PCRE. We give an explicit
- error. */
-
- case CHAR_l:
- case CHAR_L:
- *errorcodeptr = ERR37;
- break;
-
- case CHAR_u:
- if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- /* In JavaScript, \u must be followed by four hexadecimal numbers.
- Otherwise it is a lowercase u letter. */
- if (MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0
- && MAX_255(ptr[2]) && g_ascii_isxdigit(ptr[2]) != 0
- && MAX_255(ptr[3]) && g_ascii_isxdigit(ptr[3]) != 0
- && MAX_255(ptr[4]) && g_ascii_isxdigit(ptr[4]) != 0)
- {
- c = 0;
- for (i = 0; i < 4; ++i)
- {
- int cc = *(++ptr);
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
-
-#ifdef COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff))
-#else
-#ifdef COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff))
-#endif
-#endif
- {
- *errorcodeptr = ERR76;
- }
- else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- }
- }
- else
- *errorcodeptr = ERR37;
- break;
-
- case CHAR_U:
- /* In JavaScript, \U is an uppercase U letter. */
- if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37;
- break;
-
- /* In a character class, \g is just a literal "g". Outside a character
- class, \g must be followed by one of a number of specific things:
-
- (1) A number, either plain or braced. If positive, it is an absolute
- backreference. If negative, it is a relative backreference. This is a Perl
- 5.10 feature.
-
- (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
- is part of Perl's movement towards a unified syntax for back references. As
- this is synonymous with \k{name}, we fudge it up by pretending it really
- was \k.
-
- (3) For Oniguruma compatibility we also support \g followed by a name or a
- number either in angle brackets or in single quotes. However, these are
- (possibly recursive) subroutine calls, _not_ backreferences. Just return
- the -ESC_g code (cf \k). */
-
- case CHAR_g:
- if (isclass) break;
- if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
- {
- c = -ESC_g;
- break;
- }
-
- /* Handle the Perl-compatible cases */
-
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *p;
- for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
- if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
- if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET)
- {
- c = -ESC_k;
- break;
- }
- braced = TRUE;
- ptr++;
- }
- else braced = FALSE;
-
- if (ptr[1] == CHAR_MINUS)
- {
- negated = TRUE;
- ptr++;
- }
- else negated = FALSE;
-
- /* The integer range is limited by the machine's int representation. */
- c = 0;
- while (IS_DIGIT(ptr[1]))
- {
- if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
- {
- c = -1;
- break;
- }
- c = c * 10 + *(++ptr) - CHAR_0;
- }
- if (((unsigned int)c) > INT_MAX) /* Integer overflow */
- {
- while (IS_DIGIT(ptr[1]))
- ptr++;
- *errorcodeptr = ERR61;
- break;
- }
-
- if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
- {
- *errorcodeptr = ERR57;
- break;
- }
-
- if (c == 0)
- {
- *errorcodeptr = ERR58;
- break;
- }
-
- if (negated)
- {
- if (c > bracount)
- {
- *errorcodeptr = ERR15;
- break;
- }
- c = bracount - (c - 1);
- }
-
- c = -(ESC_REF + c);
- break;
-
- /* The handling of escape sequences consisting of a string of digits
- starting with one that is not zero is not straightforward. By experiment,
- the way Perl works seems to be as follows:
-
- Outside a character class, the digits are read as a decimal number. If the
- number is less than 10, or if there are that many previous extracting
- left brackets, then it is a back reference. Otherwise, up to three octal
- digits are read to form an escaped byte. Thus \123 is likely to be octal
- 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
- value is greater than 377, the least significant 8 bits are taken. Inside a
- character class, \ followed by a digit is always an octal number. */
-
- case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
- case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
-
- if (!isclass)
- {
- oldptr = ptr;
- /* The integer range is limited by the machine's int representation. */
- c -= CHAR_0;
- while (IS_DIGIT(ptr[1]))
- {
- if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
- {
- c = -1;
- break;
- }
- c = c * 10 + *(++ptr) - CHAR_0;
- }
- if (((unsigned int)c) > INT_MAX) /* Integer overflow */
- {
- while (IS_DIGIT(ptr[1]))
- ptr++;
- *errorcodeptr = ERR61;
- break;
- }
- if (c < 10 || c <= bracount)
- {
- c = -(ESC_REF + c);
- break;
- }
- ptr = oldptr; /* Put the pointer back and fall through */
- }
-
- /* Handle an octal number following \. If the first digit is 8 or 9, Perl
- generates a binary zero byte and treats the digit as a following literal.
- Thus we have to pull back the pointer by one. */
-
- if ((c = *ptr) >= CHAR_8)
- {
- ptr--;
- c = 0;
- break;
- }
-
- /* \0 always starts an octal number, but we may drop through to here with a
- larger first octal digit. The original code used just to take the least
- significant 8 bits of octal numbers (I think this is what early Perls used
- to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
- but no more than 3 octal digits. */
-
- case CHAR_0:
- c -= CHAR_0;
- while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
- c = c * 8 + *(++ptr) - CHAR_0;
-#ifdef COMPILE_PCRE8
- if (!utf && c > 0xff) *errorcodeptr = ERR51;
-#endif
- break;
-
- /* \x is complicated. \x{ddd} is a character number which can be greater
- than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
- If not, { is treated as a data character. */
-
- case CHAR_x:
- if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- /* In JavaScript, \x must be followed by two hexadecimal numbers.
- Otherwise it is a lowercase x letter. */
- if (MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0
- && MAX_255(ptr[2]) && g_ascii_isxdigit(ptr[2]) != 0)
- {
- c = 0;
- for (i = 0; i < 2; ++i)
- {
- int cc = *(++ptr);
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
- }
- break;
- }
-
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *pt = ptr + 2;
-
- c = 0;
- while (MAX_255(*pt) && g_ascii_isxdigit(*pt) != 0)
- {
- int cc = *pt++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
-
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
-
-#ifdef COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; }
-#else
-#ifdef COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; }
-#endif
-#endif
- }
-
- if (c < 0)
- {
- while (MAX_255(*pt) && g_ascii_isxdigit(*pt) != 0) pt++;
- *errorcodeptr = ERR34;
- }
-
- if (*pt == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- ptr = pt;
- break;
- }
-
- /* If the sequence of hex digits does not end with '}', then we don't
- recognize this construct; fall through to the normal \x handling. */
- }
-
- /* Read just a single-byte hex-defined char */
-
- c = 0;
- while (i++ < 2 && MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0)
- {
- int cc; /* Some compilers don't like */
- cc = *(++ptr); /* ++ in initializers */
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
- break;
-
- /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
- An error is given if the byte following \c is not an ASCII character. This
- coding is ASCII-specific, but then the whole concept of \cx is
- ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
-
- case CHAR_c:
- c = *(++ptr);
- if (c == 0)
- {
- *errorcodeptr = ERR2;
- break;
- }
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (c > 127) /* Excludes all non-ASCII in either mode */
- {
- *errorcodeptr = ERR68;
- break;
- }
- if (c >= CHAR_a && c <= CHAR_z) c -= 32;
- c ^= 0x40;
-#else /* EBCDIC coding */
- if (c >= CHAR_a && c <= CHAR_z) c += 64;
- c ^= 0xC0;
-#endif
- break;
-
- /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
- other alphanumeric following \ is an error if PCRE_EXTRA was set;
- otherwise, for Perl compatibility, it is a literal. This code looks a bit
- odd, but there used to be some cases other than the default, and there may
- be again in future, so I haven't "optimized" it. */
-
- default:
- if ((options & PCRE_EXTRA) != 0) switch(c)
- {
- default:
- *errorcodeptr = ERR3;
- break;
- }
- break;
- }
- }
-
-/* Perl supports \N{name} for character names, as well as plain \N for "not
-newline". PCRE does not support \N{name}. However, it does support
-quantification such as \N{2,3}. */
-
-if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
- !is_counted_repeat(ptr+2))
- *errorcodeptr = ERR37;
-
-/* If PCRE_UCP is set, we change the values for \d etc. */
-
-if ((options & PCRE_UCP) != 0 && c <= -ESC_D && c >= -ESC_w)
- c -= (ESC_DU - ESC_D);
-
-/* Set the pointer to the final character before returning. */
-
-*ptrptr = ptr;
-return c;
-}
-
-
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Handle \P and \p *
-*************************************************/
-
-/* This function is called after \P or \p has been encountered, provided that
-PCRE is compiled with support for Unicode properties. On entry, ptrptr is
-pointing at the P or p. On exit, it is pointing at the final character of the
-escape sequence.
-
-Argument:
- ptrptr points to the pattern position pointer
- negptr points to a boolean that is set TRUE for negation else FALSE
- dptr points to an int that is set to the detailed property value
- errorcodeptr points to the error code variable
-
-Returns: type value from ucp_type_table, or -1 for an invalid type
-*/
-
-static int
-get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
-{
-int c, i, bot, top;
-const pcre_uchar *ptr = *ptrptr;
-pcre_uchar name[32];
-
-c = *(++ptr);
-if (c == 0) goto ERROR_RETURN;
-
-*negptr = FALSE;
-
-/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
-negation. */
-
-if (c == CHAR_LEFT_CURLY_BRACKET)
- {
- if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
- {
- *negptr = TRUE;
- ptr++;
- }
- for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++)
- {
- c = *(++ptr);
- if (c == 0) goto ERROR_RETURN;
- if (c == CHAR_RIGHT_CURLY_BRACKET) break;
- name[i] = c;
- }
- if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
- name[i] = 0;
- }
-
-/* Otherwise there is just one following character */
-
-else
- {
- name[0] = c;
- name[1] = 0;
- }
-
-*ptrptr = ptr;
-
-/* Search for a recognized property name using binary chop */
-
-bot = 0;
-top = PRIV(utt_size);
-
-while (bot < top)
- {
- i = (bot + top) >> 1;
- c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
- if (c == 0)
- {
- *dptr = PRIV(utt)[i].value;
- return PRIV(utt)[i].type;
- }
- if (c > 0) bot = i + 1; else top = i;
- }
-
-*errorcodeptr = ERR47;
-*ptrptr = ptr;
-return -1;
-
-ERROR_RETURN:
-*errorcodeptr = ERR46;
-*ptrptr = ptr;
-return -1;
-}
-#endif
-
-
-
-
-/*************************************************
-* Read repeat counts *
-*************************************************/
-
-/* Read an item of the form {n,m} and return the values. This is called only
-after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
-so the syntax is guaranteed to be correct, but we need to check the values.
-
-Arguments:
- p pointer to first char after '{'
- minp pointer to int for min
- maxp pointer to int for max
- returned as -1 if no max
- errorcodeptr points to error code variable
-
-Returns: pointer to '}' on success;
- current ptr on error, with errorcodeptr set non-zero
-*/
-
-static const pcre_uchar *
-read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
-{
-int min = 0;
-int max = -1;
-
-/* Read the minimum value and do a paranoid check: a negative value indicates
-an integer overflow. */
-
-while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0;
-if (min < 0 || min > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
-
-/* Read the maximum value if there is one, and again do a paranoid on its size.
-Also, max must not be less than min. */
-
-if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
- {
- if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
- {
- max = 0;
- while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0;
- if (max < 0 || max > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
- if (max < min)
- {
- *errorcodeptr = ERR4;
- return p;
- }
- }
- }
-
-/* Fill in the required variables, and pass back the pointer to the terminating
-'}'. */
-
-*minp = min;
-*maxp = max;
-return p;
-}
-
-
-
-/*************************************************
-* Subroutine for finding forward reference *
-*************************************************/
-
-/* This recursive function is called only from find_parens() below. The
-top-level call starts at the beginning of the pattern. All other calls must
-start at a parenthesis. It scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. Recursion is used to keep
-track of subpatterns that reset the capturing group numbers - the (?| feature.
-
-This function was originally called only from the second pass, in which we know
-that if (?< or (?' or (?P< is encountered, the name will be correctly
-terminated because that is checked in the first pass. There is now one call to
-this function in the first pass, to check for a recursive back reference by
-name (so that we can make the whole group atomic). In this case, we need check
-only up to the current position in the pattern, and that is still OK because
-and previous occurrences will have been checked. To make this work, the test
-for "end of pattern" is a check against cd->end_pattern in the main loop,
-instead of looking for a binary zero. This means that the special first-pass
-call can adjust cd->end_pattern temporarily. (Checks for binary zero while
-processing items within the loop are OK, because afterwards the main loop will
-terminate.)
-
-Arguments:
- ptrptr address of the current character pointer (updated)
- cd compile background data
- name name to seek, or NULL if seeking a numbered subpattern
- lorn name length, or subpattern number if name is NULL
- xmode TRUE if we are in /x mode
- utf TRUE if we are in UTF-8 / UTF-16 mode
- count pointer to the current capturing subpattern number (updated)
-
-Returns: the number of the named subpattern, or -1 if not found
-*/
-
-static int
-find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
- BOOL xmode, BOOL utf, int *count)
-{
-pcre_uchar *ptr = *ptrptr;
-int start_count = *count;
-int hwm_count = start_count;
-BOOL dup_parens = FALSE;
-
-/* If the first character is a parenthesis, check on the type of group we are
-dealing with. The very first call may not start with a parenthesis. */
-
-if (ptr[0] == CHAR_LEFT_PARENTHESIS)
- {
- /* Handle specials such as (*SKIP) or (*UTF8) etc. */
-
- if (ptr[1] == CHAR_ASTERISK) ptr += 2;
-
- /* Handle a normal, unnamed capturing parenthesis. */
-
- else if (ptr[1] != CHAR_QUESTION_MARK)
- {
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- ptr++;
- }
-
- /* All cases now have (? at the start. Remember when we are in a group
- where the parenthesis numbers are duplicated. */
-
- else if (ptr[2] == CHAR_VERTICAL_LINE)
- {
- ptr += 3;
- dup_parens = TRUE;
- }
-
- /* Handle comments; all characters are allowed until a ket is reached. */
-
- else if (ptr[2] == CHAR_NUMBER_SIGN)
- {
- for (ptr += 3; *ptr != 0; ptr++) if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
- goto FAIL_EXIT;
- }
-
- /* Handle a condition. If it is an assertion, just carry on so that it
- is processed as normal. If not, skip to the closing parenthesis of the
- condition (there can't be any nested parens). */
-
- else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
- {
- ptr += 2;
- if (ptr[1] != CHAR_QUESTION_MARK)
- {
- while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr != 0) ptr++;
- }
- }
-
- /* Start with (? but not a condition. */
-
- else
- {
- ptr += 2;
- if (*ptr == CHAR_P) ptr++; /* Allow optional P */
-
- /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
-
- if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
- ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
- {
- int term;
- const pcre_uchar *thisname;
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- term = *ptr++;
- if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
- thisname = ptr;
- while (*ptr != term) ptr++;
- if (name != NULL && lorn == ptr - thisname &&
- STRNCMP_UC_UC(name, thisname, lorn) == 0)
- return *count;
- term++;
- }
- }
- }
-
-/* Past any initial parenthesis handling, scan for parentheses or vertical
-bars. Stop if we get to cd->end_pattern. Note that this is important for the
-first-pass call when this value is temporarily adjusted to stop at the current
-position. So DO NOT change this to a test for binary zero. */
-
-for (; ptr < cd->end_pattern; ptr++)
- {
- /* Skip over backslashed characters and also entire \Q...\E */
-
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == 0) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == 0) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
-
- /* Skip over character classes; this logic must be similar to the way they
- are handled for real. If the first character is '^', skip it. Also, if the
- first few characters (either before or after ^) are \Q\E or \E we skip them
- too. This makes for compatibility with Perl. Note the use of STR macros to
- encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
-
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
- {
- BOOL negate_class = FALSE;
- for (;;)
- {
- if (ptr[1] == CHAR_BACKSLASH)
- {
- if (ptr[2] == CHAR_E)
- ptr+= 2;
- else if (STRNCMP_UC_C8(ptr + 2,
- STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 4;
- else
- break;
- }
- else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
- {
- negate_class = TRUE;
- ptr++;
- }
- else break;
- }
-
- /* If the next character is ']', it is a data character that must be
- skipped, except in JavaScript compatibility mode. */
-
- if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
- (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
- ptr++;
-
- while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
- {
- if (*ptr == 0) return -1;
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == 0) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == 0) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
- }
- continue;
- }
-
- /* Skip comments in /x mode */
-
- if (xmode && *ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != 0)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr == 0) goto FAIL_EXIT;
- continue;
- }
-
- /* Check for the special metacharacters */
-
- if (*ptr == CHAR_LEFT_PARENTHESIS)
- {
- int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
- if (rc > 0) return rc;
- if (*ptr == 0) goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_RIGHT_PARENTHESIS)
- {
- if (dup_parens && *count < hwm_count) *count = hwm_count;
- goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
- {
- if (*count > hwm_count) hwm_count = *count;
- *count = start_count;
- }
- }
-
-FAIL_EXIT:
-*ptrptr = ptr;
-return -1;
-}
-
-
-
-
-/*************************************************
-* Find forward referenced subpattern *
-*************************************************/
-
-/* This function scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. This is used for forward
-references to subpatterns. We used to be able to start this scan from the
-current compiling point, using the current count value from cd->bracount, and
-do it all in a single loop, but the addition of the possibility of duplicate
-subpattern numbers means that we have to scan from the very start, in order to
-take account of such duplicates, and to use a recursive function to keep track
-of the different types of group.
-
-Arguments:
- cd compile background data
- name name to seek, or NULL if seeking a numbered subpattern
- lorn name length, or subpattern number if name is NULL
- xmode TRUE if we are in /x mode
- utf TRUE if we are in UTF-8 / UTF-16 mode
-
-Returns: the number of the found subpattern, or -1 if not found
-*/
-
-static int
-find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
- BOOL utf)
-{
-pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
-int count = 0;
-int rc;
-
-/* If the pattern does not start with an opening parenthesis, the first call
-to find_parens_sub() will scan right to the end (if necessary). However, if it
-does start with a parenthesis, find_parens_sub() will return when it hits the
-matching closing parens. That is why we have to have a loop. */
-
-for (;;)
- {
- rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
- if (rc > 0 || *ptr++ == 0) break;
- }
-
-return rc;
-}
-
-
-
-
-/*************************************************
-* Find first significant op code *
-*************************************************/
-
-/* This is called by several functions that scan a compiled expression looking
-for a fixed first character, or an anchoring op code etc. It skips over things
-that do not influence this. For some calls, it makes sense to skip negative
-forward and all backward assertions, and also the \b assertion; for others it
-does not.
-
-Arguments:
- code pointer to the start of the group
- skipassert TRUE if certain assertions are to be skipped
-
-Returns: pointer to the first significant opcode
-*/
-
-static const pcre_uchar*
-first_significant_code(const pcre_uchar *code, BOOL skipassert)
-{
-for (;;)
- {
- switch ((int)*code)
- {
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- if (!skipassert) return code;
- do code += GET(code, 1); while (*code == OP_ALT);
- code += PRIV(OP_lengths)[*code];
- break;
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- if (!skipassert) return code;
- /* Fall through */
-
- case OP_CALLOUT:
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- code += PRIV(OP_lengths)[*code];
- break;
-
- default:
- return code;
- }
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Find the fixed length of a branch *
-*************************************************/
-
-/* Scan a branch and compute the fixed length of subject that will match it,
-if the length is fixed. This is needed for dealing with backward assertions.
-In UTF8 mode, the result is in characters rather than bytes. The branch is
-temporarily terminated with OP_END when this function is called.
-
-This function is called when a backward assertion is encountered, so that if it
-fails, the error message can point to the correct place in the pattern.
-However, we cannot do this when the assertion contains subroutine calls,
-because they can be forward references. We solve this by remembering this case
-and doing the check at the end; a flag specifies which mode we are running in.
-
-Arguments:
- code points to the start of the pattern (the bracket)
- utf TRUE in UTF-8 / UTF-16 mode
- atend TRUE if called when the pattern is complete
- cd the "compile data" structure
-
-Returns: the fixed length,
- or -1 if there is no fixed length,
- or -2 if \C was encountered (in UTF-8 mode only)
- or -3 if an OP_RECURSE item was encountered and atend is FALSE
- or -4 if an unknown opcode was encountered (internal error)
-*/
-
-static int
-find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
-{
-int length = -1;
-
-int branchlength = 0;
-pcre_uchar *cc = code + 1 + LINK_SIZE;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
- {
- int d;
- pcre_uchar *ce, *cs;
- int op = *cc;
-
- switch (op)
- {
- /* We only need to continue for OP_CBRA (normal capturing bracket) and
- OP_BRA (normal non-capturing bracket) because the other variants of these
- opcodes are all concerned with unlimited repeated groups, which of course
- are not of fixed length. */
-
- case OP_CBRA:
- case OP_BRA:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_COND:
- d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested call.
- If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
- an ALT. If it is END it's the end of the outer call. All can be handled by
- the same code. Note that we must not include the OP_KETRxxx opcodes here,
- because they all imply an unlimited repeat. */
-
- case OP_ALT:
- case OP_KET:
- case OP_END:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- if (length < 0) length = branchlength;
- else if (length != branchlength) return -1;
- if (*cc != OP_ALT) return length;
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- break;
-
- /* A true recursion implies not fixed length, but a subroutine call may
- be OK. If the subroutine is a forward reference, we can't deal with
- it until the end of the pattern, so return -3. */
-
- case OP_RECURSE:
- if (!atend) return -3;
- cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
- do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
- if (cc > cs && cc < ce) return -1; /* Recursion */
- d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
- if (d < 0) return d;
- branchlength += d;
- cc += 1 + LINK_SIZE;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Skip over things that don't match chars */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += cc[1] + PRIV(OP_lengths)[*cc];
- break;
-
- case OP_CALLOUT:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_CREF:
- case OP_DEF:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_EOD:
- case OP_EODN:
- case OP_FAIL:
- case OP_NCREF:
- case OP_NRREF:
- case OP_NOT_WORD_BOUNDARY:
- case OP_PRUNE:
- case OP_REVERSE:
- case OP_RREF:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_SOD:
- case OP_SOM:
- case OP_THEN:
- case OP_WORD_BOUNDARY:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Handle literal characters */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- need to skip over a multibyte character in UTF8 mode. */
-
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
- cc += 1 + IMM2_SIZE + 1;
- break;
-
- /* Handle single-char matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_HSPACE:
- case OP_VSPACE:
- case OP_NOT_HSPACE:
- case OP_NOT_VSPACE:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- branchlength++;
- cc++;
- break;
-
- /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
- otherwise \C is coded as OP_ALLANY. */
-
- case OP_ANYBYTE:
- return -2;
-
- /* Check a class for variable quantification */
-
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
- case OP_XCLASS:
- cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
- /* Fall through */
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- cc += PRIV(OP_lengths)[OP_CLASS];
-
- switch (*cc)
- {
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- return -1;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
- branchlength += GET2(cc,1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- branchlength++;
- }
- break;
-
- /* Anything else is variable length */
-
- case OP_ANYNL:
- case OP_BRAMINZERO:
- case OP_BRAPOS:
- case OP_BRAPOSZERO:
- case OP_BRAZERO:
- case OP_CBRAPOS:
- case OP_EXTUNI:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_REF:
- case OP_REFI:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- case OP_SCOND:
- case OP_SKIPZERO:
- case OP_STAR:
- case OP_STARI:
- case OP_TYPEMINPLUS:
- case OP_TYPEMINQUERY:
- case OP_TYPEMINSTAR:
- case OP_TYPEMINUPTO:
- case OP_TYPEPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSUPTO:
- case OP_TYPEQUERY:
- case OP_TYPESTAR:
- case OP_TYPEUPTO:
- case OP_UPTO:
- case OP_UPTOI:
- return -1;
-
- /* Catch unrecognized opcodes so that when new ones are added they
- are not forgotten, as has happened in the past. */
-
- default:
- return -4;
- }
- }
-/* Control never gets here */
-}
-
-
-
-
-/*************************************************
-* Scan compiled regex for specific bracket *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds a
-capturing bracket with the given number, or, if the number is negative, an
-instance of OP_REVERSE for a lookbehind. The function is global in the C sense
-so that it can be called from pcre_study() when finding the minimum matching
-length.
-
-Arguments:
- code points to start of expression
- utf TRUE in UTF-8 / UTF-16 mode
- number the required bracket number or negative to find a lookbehind
-
-Returns: pointer to the opcode for the bracket, or NULL if not found
-*/
-
-const pcre_uchar *
-PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number)
-{
-for (;;)
- {
- int c = *code;
-
- if (c == OP_END) return NULL;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Handle recursion */
-
- else if (c == OP_REVERSE)
- {
- if (number < 0) return (pcre_uchar *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Handle capturing bracket */
-
- else if (c == OP_CBRA || c == OP_SCBRA ||
- c == OP_CBRAPOS || c == OP_SCBRAPOS)
- {
- int n = GET2(code, 1+LINK_SIZE);
- if (n == number) return (pcre_uchar *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
- must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP
- || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
- break;
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- code += code[1];
- break;
-
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed by
- a multi-byte character. The length in the table is a minimum, so we have to
- arrange to skip the extra bytes. */
-
-#ifdef SUPPORT_UTF
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled regex for recursion reference *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds an
-instance of OP_RECURSE.
-
-Arguments:
- code points to start of expression
- utf TRUE in UTF-8 / UTF-16 mode
-
-Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
-*/
-
-static const pcre_uchar *
-find_recurse(const pcre_uchar *code, BOOL utf)
-{
-for (;;)
- {
- int c = *code;
- if (c == OP_END) return NULL;
- if (c == OP_RECURSE) return code;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
- must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEPOSUPTO:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- if (code[1 + IMM2_SIZE] == OP_PROP
- || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
- break;
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- code += code[1];
- break;
-
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed
- by a multi-byte character. The length in the table is a minimum, so we have
- to arrange to skip the extra bytes. */
-
-#ifdef SUPPORT_UTF
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- 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 (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled branch for non-emptiness *
-*************************************************/
-
-/* This function scans through a branch of a compiled pattern to see whether it
-can match the empty string or not. It is called from could_be_empty()
-below and from compile_branch() when checking for an unlimited repeat of a
-group that can match nothing. Note that first_significant_code() skips over
-backward and negative forward assertions when its final argument is TRUE. If we
-hit an unclosed bracket, we return "empty" - this means we've struck an inner
-bracket whose current branch will already have been scanned.
-
-Arguments:
- code points to start of search
- endcode points to where to stop
- utf TRUE if in UTF-8 / UTF-16 mode
- cd contains pointers to tables etc.
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
- BOOL utf, compile_data *cd)
-{
-int c;
-for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
- code < endcode;
- code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
- {
- const pcre_uchar *ccode;
-
- c = *code;
-
- /* Skip over forward assertions; the other assertions are skipped by
- first_significant_code() with a TRUE final argument. */
-
- if (c == OP_ASSERT)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* For a recursion/subroutine call, if its end has been reached, which
- implies a backward reference subroutine call, we can scan it. If it's a
- forward reference subroutine call, we can't. To detect forward reference
- we have to scan up the list that is kept in the workspace. This function is
- called only when doing the real compile, not during the pre-compile that
- measures the size of the compiled pattern. */
-
- if (c == OP_RECURSE)
- {
- const pcre_uchar *scode;
- BOOL empty_branch;
-
- /* Test for forward reference */
-
- for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
- if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE;
-
- /* Not a forward reference, test for completed backward reference */
-
- empty_branch = FALSE;
- scode = cd->start_code + GET(code, 1);
- if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
-
- /* Completed backwards reference */
-
- do
- {
- if (could_be_empty_branch(scode, endcode, utf, cd))
- {
- empty_branch = TRUE;
- break;
- }
- scode += GET(scode, 1);
- }
- while (*scode == OP_ALT);
-
- if (!empty_branch) return FALSE; /* All branches are non-empty */
- continue;
- }
-
- /* Groups with zero repeats can of course be empty; skip them. */
-
- if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
- c == OP_BRAPOSZERO)
- {
- code += PRIV(OP_lengths)[c];
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* A nested group that is already marked as "could be empty" can just be
- skipped. */
-
- if (c == OP_SBRA || c == OP_SBRAPOS ||
- c == OP_SCBRA || c == OP_SCBRAPOS)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* For other groups, scan the branches. */
-
- if (c == OP_BRA || c == OP_BRAPOS ||
- c == OP_CBRA || c == OP_CBRAPOS ||
- c == OP_ONCE || c == OP_ONCE_NC ||
- c == OP_COND)
- {
- BOOL empty_branch;
- if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
-
- /* If a conditional group has only one branch, there is a second, implied,
- empty branch, so just skip over the conditional, because it could be empty.
- Otherwise, scan the individual branches of the group. */
-
- if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
- code += GET(code, 1);
- else
- {
- empty_branch = FALSE;
- do
- {
- if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
- empty_branch = TRUE;
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- if (!empty_branch) return FALSE; /* All branches are non-empty */
- }
-
- c = *code;
- continue;
- }
-
- /* Handle the other opcodes */
-
- switch (c)
- {
- /* Check for quantifiers after a class. XCLASS is used for classes that
- cannot be represented just by a bit map. This includes negated single
- high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
- actual length is stored in the compiled code, so we must update "code"
- here. */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- ccode = code += GET(code, 1);
- goto CHECK_CLASS_REPEAT;
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- ccode = code + PRIV(OP_lengths)[OP_CLASS];
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- CHECK_CLASS_REPEAT:
-#endif
-
- switch (*ccode)
- {
- case OP_CRSTAR: /* These could be empty; continue */
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- break;
-
- default: /* Non-repeat => class must match */
- case OP_CRPLUS: /* These repeats aren't empty */
- case OP_CRMINPLUS:
- return FALSE;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
- break;
- }
- break;
-
- /* Opcodes that must match a character */
-
- case OP_PROP:
- case OP_NOTPROP:
- case OP_EXTUNI:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_EXACT:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- case OP_NOTEXACT:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEEXACT:
- return FALSE;
-
- /* These are going to continue, as they may be empty, but we have to
- fudge the length for the \p and \P cases. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- /* Same for these */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP
- || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
- break;
-
- /* End of branch */
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_ALT:
- return TRUE;
-
- /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
- MINUPTO, and POSUPTO may be followed by a multibyte character */
-
-#ifdef SUPPORT_UTF
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
- break;
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
- break;
-#endif
-
- /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
- string. */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- code += code[1];
- break;
-
- case OP_THEN_ARG:
- code += code[1];
- break;
-
- /* None of the remaining opcodes are required to match a character. */
-
- default:
- break;
- }
- }
-
-return TRUE;
-}
-
-
-
-/*************************************************
-* Scan compiled regex for non-emptiness *
-*************************************************/
-
-/* This function is called to check for left recursive calls. We want to check
-the current branch of the current pattern to see if it could match the empty
-string. If it could, we must look outwards for branches at other levels,
-stopping when we pass beyond the bracket which is the subject of the recursion.
-This function is called only during the real compile, not during the
-pre-compile.
-
-Arguments:
- code points to start of the recursion
- endcode points to where to stop (current RECURSE item)
- bcptr points to the chain of current (unclosed) branch starts
- utf TRUE if in UTF-8 / UTF-16 mode
- cd pointers to tables etc
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
- branch_chain *bcptr, BOOL utf, compile_data *cd)
-{
-while (bcptr != NULL && bcptr->current_branch >= code)
- {
- if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
- return FALSE;
- bcptr = bcptr->outer;
- }
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for POSIX class syntax *
-*************************************************/
-
-/* This function is called when the sequence "[:" or "[." or "[=" is
-encountered in a character class. It checks whether this is followed by a
-sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
-reach an unescaped ']' without the special preceding character, return FALSE.
-
-Originally, this function only recognized a sequence of letters between the
-terminators, but it seems that Perl recognizes any sequence of characters,
-though of course unknown POSIX names are subsequently rejected. Perl gives an
-"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
-didn't consider this to be a POSIX class. Likewise for [:1234:].
-
-The problem in trying to be exactly like Perl is in the handling of escapes. We
-have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
-class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
-below handles the special case of \], but does not try to do any other escape
-processing. This makes it different from Perl for cases such as [:l\ower:]
-where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
-"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
-I think.
-
-A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
-It seems that the appearance of a nested POSIX class supersedes an apparent
-external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
-a digit.
-
-In Perl, unescaped square brackets may also appear as part of class names. For
-example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
-[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
-seem right at all. PCRE does not allow closing square brackets in POSIX class
-names.
-
-Arguments:
- ptr pointer to the initial [
- endptr where to return the end pointer
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr)
-{
-int terminator; /* Don't combine these lines; the Solaris cc */
-terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
-for (++ptr; *ptr != 0; ptr++)
- {
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- ptr++;
- else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
- else
- {
- if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- *endptr = ptr;
- return TRUE;
- }
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
- (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, endptr))
- return FALSE;
- }
- }
-return FALSE;
-}
-
-
-
-
-/*************************************************
-* Check POSIX class name *
-*************************************************/
-
-/* This function is called to check the name given in a POSIX-style class entry
-such as [:alnum:].
-
-Arguments:
- ptr points to the first letter
- len the length of the name
-
-Returns: a value representing the name, or -1 if unknown
-*/
-
-static int
-check_posix_name(const pcre_uchar *ptr, int len)
-{
-const char *pn = posix_names;
-int yield = 0;
-while (posix_name_lengths[yield] != 0)
- {
- if (len == posix_name_lengths[yield] &&
- STRNCMP_UC_C8(ptr, pn, len) == 0) return yield;
- pn += posix_name_lengths[yield] + 1;
- yield++;
- }
-return -1;
-}
-
-
-/*************************************************
-* Adjust OP_RECURSE items in repeated group *
-*************************************************/
-
-/* OP_RECURSE items contain an offset from the start of the regex to the group
-that is referenced. This means that groups can be replicated for fixed
-repetition simply by copying (because the recursion is allowed to refer to
-earlier groups that are outside the current group). However, when a group is
-optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
-inserted before it, after it has been compiled. This means that any OP_RECURSE
-items within it that refer to the group itself or any contained groups have to
-have their offsets adjusted. That one of the jobs of this function. Before it
-is called, the partially compiled regex must be temporarily terminated with
-OP_END.
-
-This function has been extended with the possibility of forward references for
-recursions and subroutine calls. It must also check the list of such references
-for the group we are dealing with. If it finds that one of the recursions in
-the current group is on this list, it adjusts the offset in the list, not the
-value in the reference (which is a group number).
-
-Arguments:
- group points to the start of the group
- adjust the amount by which the group is to be moved
- utf TRUE in UTF-8 / UTF-16 mode
- cd contains pointers to tables etc.
- save_hwm the hwm forward reference pointer at the start of the group
-
-Returns: nothing
-*/
-
-static void
-adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
- pcre_uchar *save_hwm)
-{
-pcre_uchar *ptr = group;
-
-while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
- {
- int offset;
- pcre_uchar *hc;
-
- /* See if this recursion is on the forward reference list. If so, adjust the
- reference. */
-
- for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
- {
- offset = GET(hc, 0);
- if (cd->start_code + offset == ptr + 1)
- {
- PUT(hc, 0, offset + adjust);
- break;
- }
- }
-
- /* Otherwise, adjust the recursion offset if it's after the start of this
- group. */
-
- if (hc >= cd->hwm)
- {
- offset = GET(ptr, 1);
- if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
- }
-
- ptr += 1 + LINK_SIZE;
- }
-}
-
-
-
-/*************************************************
-* Insert an automatic callout point *
-*************************************************/
-
-/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
-callout points before each pattern item.
-
-Arguments:
- code current code pointer
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: new code pointer
-*/
-
-static pcre_uchar *
-auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
-{
-*code++ = OP_CALLOUT;
-*code++ = 255;
-PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
-PUT(code, LINK_SIZE, 0); /* Default length */
-return code + 2 * LINK_SIZE;
-}
-
-
-
-/*************************************************
-* Complete a callout item *
-*************************************************/
-
-/* A callout item contains the length of the next item in the pattern, which
-we can't fill in till after we have reached the relevant point. This is used
-for both automatic and manual callouts.
-
-Arguments:
- previous_callout points to previous callout item
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: nothing
-*/
-
-static void
-complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
-{
-int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
-PUT(previous_callout, 2 + LINK_SIZE, length);
-}
-
-
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Get othercase range *
-*************************************************/
-
-/* This function is passed the start and end of a class range, in UTF-8 mode
-with UCP support. It searches up the characters, looking for internal ranges of
-characters in the "other" case. Each call returns the next one, updating the
-start address.
-
-Arguments:
- cptr points to starting character value; updated
- d end value
- ocptr where to put start of othercase range
- odptr where to put end of othercase range
-
-Yield: TRUE when range returned; FALSE when no more
-*/
-
-static BOOL
-get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr,
- unsigned int *odptr)
-{
-unsigned int c, othercase, next;
-
-for (c = *cptr; c <= d; c++)
- { if ((othercase = UCD_OTHERCASE(c)) != c) break; }
-
-if (c > d) return FALSE;
-
-*ocptr = othercase;
-next = othercase + 1;
-
-for (++c; c <= d; c++)
- {
- if (UCD_OTHERCASE(c) != next) break;
- next++;
- }
-
-*odptr = next - 1;
-*cptr = c;
-
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check a character and a property *
-*************************************************/
-
-/* This function is called by check_auto_possessive() when a property item
-is adjacent to a fixed character.
-
-Arguments:
- c the character
- ptype the property type
- pdata the data for the type
- negated TRUE if it's a negated property (\P or \p{^)
-
-Returns: TRUE if auto-possessifying is OK
-*/
-
-static BOOL
-check_char_prop(int c, int ptype, int pdata, BOOL negated)
-{
-const pcre_uint8 chartype = UCD_CHARTYPE(c);
-switch(ptype)
- {
- case PT_LAMP:
- return (chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == negated;
-
- case PT_GC:
- return (pdata == PRIV(ucp_gentype)[chartype]) == negated;
-
- case PT_PC:
- return (pdata == chartype) == negated;
-
- case PT_SC:
- return (pdata == UCD_SCRIPT(c)) == negated;
-
- /* These are specials */
-
- case PT_ALNUM:
- return (PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N) == negated;
-
- case PT_SPACE: /* Perl space */
- return (PRIV(ucp_gentype)[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)[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)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == negated;
- }
-return FALSE;
-}
-#endif /* SUPPORT_UCP */
-
-
-
-/*************************************************
-* Check if auto-possessifying is possible *
-*************************************************/
-
-/* This function is called for unlimited repeats of certain items, to see
-whether the next thing could possibly match the repeated item. If not, it makes
-sense to automatically possessify the repeated item.
-
-Arguments:
- previous pointer to the repeated opcode
- utf TRUE in UTF-8 / UTF-16 mode
- ptr next character in pattern
- options options bits
- cd contains pointers to tables etc.
-
-Returns: TRUE if possessifying is wanted
-*/
-
-static BOOL
-check_auto_possessive(const pcre_uchar *previous, BOOL utf,
- const pcre_uchar *ptr, int options, compile_data *cd)
-{
-pcre_int32 c, next;
-int op_code = *previous++;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != 0)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next item is one that we can handle, get its value. A non-negative
-value is a character, a negative value is an escape value. */
-
-if (*ptr == CHAR_BACKSLASH)
- {
- int temperrorcode = 0;
- next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* Point after the escape sequence */
- }
-else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
- {
-#ifdef SUPPORT_UTF
- if (utf) { GETCHARINC(next, ptr); } else
-#endif
- next = *ptr++;
- }
-else return FALSE;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != 0)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next thing is itself optional, we have to give up. */
-
-if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
-/* Now compare the next item with the previous opcode. First, handle cases when
-the next item is a character. */
-
-if (next >= 0) switch(op_code)
- {
- case OP_CHAR:
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- return c != next;
-
- /* For CHARI (caseless character) we must check the other case. If we have
- Unicode property support, we can use it to test the other case of
- high-valued characters. */
-
- case OP_CHARI:
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- if (c == next) return FALSE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE((unsigned int)next);
-#else
- othercase = NOTACHAR;
-#endif
- return (unsigned int)c != othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
-
- case OP_NOT:
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- return c == next;
-
- case OP_NOTI:
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- if (c == next) return TRUE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE((unsigned int)next);
-#else
- othercase = NOTACHAR;
-#endif
- return (unsigned int)c == othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
-
- /* 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)
- {
- case 0x09:
- case 0x20:
- case 0xa0:
- case 0x1680:
- case 0x180e:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- case 0x2004:
- case 0x2005:
- case 0x2006:
- case 0x2007:
- case 0x2008:
- case 0x2009:
- case 0x200A:
- case 0x202f:
- case 0x205f:
- case 0x3000:
- return op_code == OP_NOT_HSPACE;
- default:
- return op_code != OP_NOT_HSPACE;
- }
-
- case OP_ANYNL:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- switch(next)
- {
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x85:
- case 0x2028:
- case 0x2029:
- return op_code == OP_NOT_VSPACE;
- default:
- return op_code != OP_NOT_VSPACE;
- }
-
-#ifdef SUPPORT_UCP
- case OP_PROP:
- return check_char_prop(next, previous[0], previous[1], FALSE);
-
- case OP_NOTPROP:
- return check_char_prop(next, previous[0], previous[1], TRUE);
-#endif
-
- default:
- return FALSE;
- }
-
-
-/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP
-is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are
-generated only when PCRE_UCP is *not* set, that is, when only ASCII
-characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are
-replaced by OP_PROP codes when PCRE_UCP is set. */
-
-switch(op_code)
- {
- case OP_CHAR:
- case OP_CHARI:
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- switch(-next)
- {
- case ESC_d:
- return c > 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)
- {
- case 0x09:
- case 0x20:
- case 0xa0:
- case 0x1680:
- case 0x180e:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- case 0x2004:
- case 0x2005:
- case 0x2006:
- case 0x2007:
- case 0x2008:
- case 0x2009:
- case 0x200A:
- case 0x202f:
- case 0x205f:
- case 0x3000:
- return -next != ESC_h;
- default:
- return -next == ESC_h;
- }
-
- case ESC_v:
- case ESC_V:
- switch(c)
- {
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x85:
- case 0x2028:
- case 0x2029:
- return -next != ESC_v;
- default:
- return -next == ESC_v;
- }
-
- /* When PCRE_UCP is set, these values get generated for \d etc. Find
- their substitutions and process them. The result will always be either
- -ESC_p or -ESC_P. Then fall through to process those values. */
-
-#ifdef SUPPORT_UCP
- case ESC_du:
- case ESC_DU:
- case ESC_wu:
- case ESC_WU:
- case ESC_su:
- case ESC_SU:
- {
- int temperrorcode = 0;
- ptr = substitutes[-next - ESC_DU];
- next = check_escape(&ptr, &temperrorcode, 0, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* For compatibility */
- }
- /* Fall through */
-
- case ESC_p:
- case ESC_P:
- {
- int ptype, pdata, errorcodeptr;
- BOOL negated;
-
- ptr--; /* Make ptr point at the p or P */
- ptype = get_ucp(&ptr, &negated, &pdata, &errorcodeptr);
- if (ptype < 0) return FALSE;
- ptr++; /* Point past the final curly ket */
-
- /* If the property item is optional, we have to give up. (When generated
- from \d etc by PCRE_UCP, this test will have been applied much earlier,
- to the original \d etc. At this point, ptr will point to a zero byte. */
-
- if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
- /* Do the property check. */
-
- return check_char_prop(c, ptype, pdata, (next == -ESC_P) != negated);
- }
-#endif
-
- default:
- return FALSE;
- }
-
- /* In principle, support for Unicode properties should be integrated here as
- well. It means re-organizing the above code so as to get hold of the property
- values before switching on the op-code. However, I wonder how many patterns
- combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set,
- these op-codes are never generated.) */
-
- case OP_DIGIT:
- return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
- next == -ESC_h || next == -ESC_v || next == -ESC_R;
-
- case OP_NOT_DIGIT:
- return next == -ESC_d;
-
- case OP_WHITESPACE:
- return next == -ESC_S || next == -ESC_d || next == -ESC_w;
-
- case OP_NOT_WHITESPACE:
- return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R;
-
- case OP_HSPACE:
- return next == -ESC_S || next == -ESC_H || next == -ESC_d ||
- next == -ESC_w || next == -ESC_v || next == -ESC_R;
-
- case OP_NOT_HSPACE:
- return next == -ESC_h;
-
- /* Can't have \S in here because VT matches \S (Perl anomaly) */
- case OP_ANYNL:
- case OP_VSPACE:
- return next == -ESC_V || next == -ESC_d || next == -ESC_w;
-
- case OP_NOT_VSPACE:
- return next == -ESC_v || next == -ESC_R;
-
- case OP_WORDCHAR:
- return next == -ESC_W || next == -ESC_s || next == -ESC_h ||
- next == -ESC_v || next == -ESC_R;
-
- case OP_NOT_WORDCHAR:
- return next == -ESC_w || next == -ESC_d;
-
- default:
- return FALSE;
- }
-
-/* Control does not reach here */
-}
-
-
-
-/*************************************************
-* Compile one branch *
-*************************************************/
-
-/* Scan the pattern, compiling it into the a vector. If the options are
-changed during the branch, the pointer is used to change the external options
-bits. This function is used during the pre-compile phase when we are trying
-to find out the amount of memory needed, as well as during the real compile
-phase. The value of lengthptr distinguishes the two phases.
-
-Arguments:
- optionsptr pointer to the option bits
- codeptr points to the pointer to the current code point
- ptrptr points to the current pattern pointer
- errorcodeptr points to error code variable
- firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
- reqcharptr set to the last literal character required, else < 0
- bcptr points to current branch chain
- cond_depth conditional nesting depth
- cd contains pointers to tables etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
- FALSE, with *errorcodeptr set non-zero on error
-*/
-
-static BOOL
-compile_branch(int *optionsptr, pcre_uchar **codeptr,
- const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr,
- pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth,
- compile_data *cd, int *lengthptr)
-{
-int repeat_type, op_type;
-int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
-int bravalue = 0;
-int greedy_default, greedy_non_default;
-pcre_int32 firstchar, reqchar;
-pcre_int32 zeroreqchar, zerofirstchar;
-pcre_int32 req_caseopt, reqvary, tempreqvary;
-int options = *optionsptr; /* May change dynamically */
-int after_manual_callout = 0;
-int length_prevgroup = 0;
-int c;
-pcre_uchar *code = *codeptr;
-pcre_uchar *last_code = code;
-pcre_uchar *orig_code = code;
-pcre_uchar *tempcode;
-BOOL inescq = FALSE;
-BOOL groupsetfirstchar = FALSE;
-const pcre_uchar *ptr = *ptrptr;
-const pcre_uchar *tempptr;
-const pcre_uchar *nestptr = NULL;
-pcre_uchar *previous = NULL;
-pcre_uchar *previous_callout = NULL;
-pcre_uchar *save_hwm = NULL;
-pcre_uint8 classbits[32];
-
-/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
-must not do this for other options (e.g. PCRE_EXTENDED) because they may change
-dynamically as we process the pattern. */
-
-#ifdef SUPPORT_UTF
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-pcre_uchar utf_chars[6];
-#else
-BOOL utf = FALSE;
-#endif
-
-/* Helper variables for OP_XCLASS opcode (for characters > 255). */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
-BOOL xclass;
-pcre_uchar *class_uchardata;
-pcre_uchar *class_uchardata_base;
-#endif
-
-#ifdef PCRE_DEBUG
-if (lengthptr != NULL) DPRINTF((">> start branch\n"));
-#endif
-
-/* Set up the default and non-default settings for greediness */
-
-greedy_default = ((options & PCRE_UNGREEDY) != 0);
-greedy_non_default = greedy_default ^ 1;
-
-/* Initialize no first byte, no required byte. REQ_UNSET means "no char
-matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed char first char; reqchar just remains unset if we never
-find one.
-
-When we hit a repeat whose minimum is zero, we may have to adjust these values
-to take the zero repeat into account. This is implemented by setting them to
-zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual
-item types that can be repeated set these backoff variables appropriately. */
-
-firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET;
-
-/* The variable req_caseopt contains either the REQ_CASELESS value
-or zero, according to the current setting of the caseless flag. The
-REQ_CASELESS leaves the lower 28 bit empty. It is added into the
-firstchar or reqchar variables to record the case status of the
-value. This is used only for ASCII characters. */
-
-req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
-
-/* Switch on next character until the end of the branch */
-
-for (;; ptr++)
- {
- BOOL negate_class;
- BOOL should_flip_negation;
- BOOL possessive_quantifier;
- BOOL is_quantifier;
- BOOL is_recurse;
- BOOL reset_bracount;
- int class_has_8bitchar;
- int class_single_char;
- int newoptions;
- int recno;
- int refsign;
- int skipbytes;
- int subreqchar;
- int subfirstchar;
- int terminator;
- int mclength;
- int tempbracount;
- pcre_uchar mcbuffer[8];
-
- /* Get next character in the pattern */
-
- c = *ptr;
-
- /* If we are at the end of a nested substitution, revert to the outer level
- string. Nesting only happens one level deep. */
-
- if (c == 0 && nestptr != NULL)
- {
- ptr = nestptr;
- nestptr = NULL;
- c = *ptr;
- }
-
- /* If we are in the pre-compile phase, accumulate the length used for the
- previous cycle of this loop. */
-
- if (lengthptr != NULL)
- {
-#ifdef PCRE_DEBUG
- if (code > cd->hwm) cd->hwm = code; /* High water info */
-#endif
- if (code > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* There is at least one situation where code goes backwards: this is the
- case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
- the class is simply eliminated. However, it is created first, so we have to
- allow memory for it. Therefore, don't ever reduce the length at this point.
- */
-
- if (code < last_code) code = last_code;
-
- /* Paranoid check for integer overflow */
-
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
-
- *lengthptr += (int)(code - last_code);
- DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr,
- (int)(code - last_code), c, c));
-
- /* If "previous" is set and it is not at the start of the work space, move
- it back to there, in order to avoid filling up the work space. Otherwise,
- if "previous" is NULL, reset the current code pointer to the start. */
-
- if (previous != NULL)
- {
- if (previous > orig_code)
- {
- memmove(orig_code, previous, IN_UCHARS(code - previous));
- code -= previous - orig_code;
- previous = orig_code;
- }
- }
- else code = orig_code;
-
- /* Remember where this code item starts so we can pick up the length
- next time round. */
-
- last_code = code;
- }
-
- /* In the real compile phase, just check the workspace used by the forward
- reference list. */
-
- else if (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN)
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* If in \Q...\E, check for the end; if not, we have a literal */
-
- if (inescq && c != 0)
- {
- if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
- {
- inescq = FALSE;
- ptr++;
- continue;
- }
- else
- {
- if (previous_callout != NULL)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
- if ((options & PCRE_AUTO_CALLOUT) != 0)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
- goto NORMAL_CHAR;
- }
- }
-
- /* Fill in length of a previous callout, except when the next thing is
- a quantifier. */
-
- is_quantifier =
- c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
- (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
-
- if (!is_quantifier && previous_callout != NULL &&
- after_manual_callout-- <= 0)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
-
- /* In extended mode, skip white space and comments. */
-
- if ((options & PCRE_EXTENDED) != 0)
- {
- if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
- if (c == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != 0)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr != 0) continue;
-
- /* Else fall through to handle end of string */
- c = 0;
- }
- }
-
- /* No auto callout for quantifiers. */
-
- if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
-
- switch(c)
- {
- /* ===================================================================*/
- case 0: /* The branch terminates at string end */
- case CHAR_VERTICAL_LINE: /* or | or ) */
- case CHAR_RIGHT_PARENTHESIS:
- *firstcharptr = firstchar;
- *reqcharptr = reqchar;
- *codeptr = code;
- *ptrptr = ptr;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += (int)(code - last_code); /* To include callout length */
- DPRINTF((">> end branch\n"));
- }
- return TRUE;
-
-
- /* ===================================================================*/
- /* Handle single-character metacharacters. In multiline mode, ^ disables
- the setting of any following char as a first character. */
-
- case CHAR_CIRCUMFLEX_ACCENT:
- previous = NULL;
- if ((options & PCRE_MULTILINE) != 0)
- {
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- *code++ = OP_CIRCM;
- }
- else *code++ = OP_CIRC;
- break;
-
- case CHAR_DOLLAR_SIGN:
- previous = NULL;
- *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
- break;
-
- /* There can never be a first char if '.' is first, whatever happens about
- repeats. The value of reqchar doesn't change either. */
-
- case CHAR_DOT:
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- zerofirstchar = firstchar;
- zeroreqchar = reqchar;
- previous = code;
- *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
- break;
-
-
- /* ===================================================================*/
- /* Character classes. If the included characters are all < 256, we build a
- 32-byte bitmap of the permitted characters, except in the special case
- where there is only one such character. For negated classes, we build the
- map as usual, then invert it at the end. However, we use a different opcode
- so that data characters > 255 can be handled correctly.
-
- If the class contains characters outside the 0-255 range, a different
- opcode is compiled. It may optionally have a bit map for characters < 256,
- but those above are are explicitly listed afterwards. A flag byte tells
- whether the bitmap is present, and whether this is a negated class or not.
-
- In JavaScript compatibility mode, an isolated ']' causes an error. In
- default (Perl) mode, it is treated as a data character. */
-
- case CHAR_RIGHT_SQUARE_BRACKET:
- if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *errorcodeptr = ERR64;
- goto FAILED;
- }
- goto NORMAL_CHAR;
-
- case CHAR_LEFT_SQUARE_BRACKET:
- previous = code;
-
- /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
- they are encountered at the top level, so we'll do that too. */
-
- if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, &tempptr))
- {
- *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31;
- goto FAILED;
- }
-
- /* If the first character is '^', set the negation flag and skip it. Also,
- if the first few characters (either before or after ^) are \Q\E or \E we
- skip them too. This makes for compatibility with Perl. */
-
- negate_class = FALSE;
- for (;;)
- {
- c = *(++ptr);
- if (c == CHAR_BACKSLASH)
- {
- if (ptr[1] == CHAR_E)
- ptr++;
- else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 3;
- else
- break;
- }
- else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
- negate_class = TRUE;
- else break;
- }
-
- /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
- an initial ']' is taken as a data character -- the code below handles
- that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
- [^] must match any character, so generate OP_ALLANY. */
-
- if (c == CHAR_RIGHT_SQUARE_BRACKET &&
- (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *code++ = negate_class? OP_ALLANY : OP_FAIL;
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- zerofirstchar = firstchar;
- break;
- }
-
- /* If a class contains a negative special such as \S, we need to flip the
- negation flag at the end, so that support for characters > 255 works
- correctly (they are all included in the class). */
-
- should_flip_negation = FALSE;
-
- /* For optimization purposes, we track some properties of the class.
- class_has_8bitchar will be non-zero, if the class contains at least one
- < 256 character. class_single_char will be 1 if the class contains only
- a single character. */
-
- class_has_8bitchar = 0;
- class_single_char = 0;
-
- /* Initialize the 32-char bit map to all zeros. We build the map in a
- temporary bit of memory, in case the class contains only 1 character (less
- than 256), because in that case the compiled code doesn't use the bit map.
- */
-
- memset(classbits, 0, 32 * sizeof(pcre_uint8));
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- xclass = FALSE; /* No chars >= 256 */
- class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */
- class_uchardata_base = class_uchardata; /* For resetting in pass 1 */
-#endif
-
- /* Process characters until ] is reached. By writing this as a "do" it
- means that an initial ] is taken as a data character. At the start of the
- loop, c contains the first byte of the character. */
-
- if (c != 0) do
- {
- const pcre_uchar *oldptr;
-
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(c))
- { /* Braces are required because the */
- GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
- }
-#endif
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- /* In the pre-compile phase, accumulate the length of any extra
- data and reset the pointer. This is so that very large classes that
- contain a zillion > 255 characters no longer overwrite the work space
- (which is on the stack). */
-
- if (lengthptr != NULL)
- {
- *lengthptr += class_uchardata - class_uchardata_base;
- class_uchardata = class_uchardata_base;
- }
-#endif
-
- /* Inside \Q...\E everything is literal except \E */
-
- if (inescq)
- {
- if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */
- {
- inescq = FALSE; /* Reset literal state */
- ptr++; /* Skip the 'E' */
- continue; /* Carry on with next */
- }
- goto CHECK_RANGE; /* Could be range if \E follows */
- }
-
- /* Handle POSIX class names. Perl allows a negation extension of the
- form [:^name:]. A square bracket that doesn't match the syntax is
- treated as a literal. We also recognize the POSIX constructions
- [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
- 5.6 and 5.8 do. */
-
- if (c == CHAR_LEFT_SQUARE_BRACKET &&
- (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
- {
- BOOL local_negate = FALSE;
- int posix_class, taboffset, tabopt;
- const pcre_uint8 *cbits = cd->cbits;
- pcre_uint8 pbits[32];
-
- if (ptr[1] != CHAR_COLON)
- {
- *errorcodeptr = ERR31;
- goto FAILED;
- }
-
- ptr += 2;
- if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
- {
- local_negate = TRUE;
- should_flip_negation = TRUE; /* Note negative special */
- ptr++;
- }
-
- posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
- if (posix_class < 0)
- {
- *errorcodeptr = ERR30;
- goto FAILED;
- }
-
- /* If matching is caseless, upper and lower are converted to
- alpha. This relies on the fact that the class table starts with
- alpha, lower, upper as the first 3 entries. */
-
- if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
- posix_class = 0;
-
- /* When PCRE_UCP is set, some of the POSIX classes are converted to
- different escape sequences that use Unicode properties. */
-
-#ifdef SUPPORT_UCP
- if ((options & PCRE_UCP) != 0)
- {
- int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
- if (posix_substitutes[pc] != NULL)
- {
- nestptr = tempptr + 1;
- ptr = posix_substitutes[pc] - 1;
- continue;
- }
- }
-#endif
- /* In the non-UCP case, we build the bit map for the POSIX class in a
- chunk of local store because we may be adding and subtracting from it,
- and we don't want to subtract bits that may be in the main map already.
- At the end we or the result into the bit map that is being built. */
-
- posix_class *= 3;
-
- /* Copy in the first table (always present) */
-
- memcpy(pbits, cbits + posix_class_maps[posix_class],
- 32 * sizeof(pcre_uint8));
-
- /* If there is a second table, add or remove it as required. */
-
- taboffset = posix_class_maps[posix_class + 1];
- tabopt = posix_class_maps[posix_class + 2];
-
- if (taboffset >= 0)
- {
- if (tabopt >= 0)
- for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
- else
- for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
- }
-
- /* Not see if we need to remove any special characters. An option
- value of 1 removes vertical space and 2 removes underscore. */
-
- if (tabopt < 0) tabopt = -tabopt;
- if (tabopt == 1) pbits[1] &= ~0x3c;
- else if (tabopt == 2) pbits[11] &= 0x7f;
-
- /* Add the POSIX table or its complement into the main table that is
- being built and we are done. */
-
- if (local_negate)
- for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
- else
- for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
-
- ptr = tempptr + 1;
- /* Every class contains at least one < 256 characters. */
- class_has_8bitchar = 1;
- /* Every class contains at least two characters. */
- class_single_char = 2;
- continue; /* End of POSIX syntax handling */
- }
-
- /* Backslash may introduce a single character, or it may introduce one
- of the specials, which just set a flag. The sequence \b is a special
- case. Inside a class (and only there) it is treated as backspace. We
- assume that other escapes have more than one character in them, so
- speculatively set both class_has_8bitchar and class_single_char bigger
- than one. Unrecognized escapes fall through and are either treated
- as literal characters (by default), or are faulted if
- PCRE_EXTRA is set. */
-
- if (c == CHAR_BACKSLASH)
- {
- c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
-
- if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
- else if (-c == ESC_N) /* \N is not supported in a class */
- {
- *errorcodeptr = ERR71;
- goto FAILED;
- }
- else if (-c == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- {
- ptr += 2; /* avoid empty string */
- }
- else inescq = TRUE;
- continue;
- }
- else if (-c == ESC_E) continue; /* Ignore orphan \E */
-
- if (c < 0)
- {
- const pcre_uint8 *cbits = cd->cbits;
- /* Every class contains at least two < 256 characters. */
- class_has_8bitchar++;
- /* Every class contains at least two characters. */
- class_single_char += 2;
-
- switch (-c)
- {
-#ifdef SUPPORT_UCP
- case ESC_du: /* These are the values given for \d etc */
- case ESC_DU: /* when PCRE_UCP is set. We replace the */
- case ESC_wu: /* escape sequence with an appropriate \p */
- case ESC_WU: /* or \P to test Unicode properties instead */
- case ESC_su: /* of the default ASCII testing. */
- case ESC_SU:
- nestptr = ptr;
- ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
- class_has_8bitchar--; /* Undo! */
- continue;
-#endif
- case ESC_d:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
- continue;
-
- case ESC_D:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
- continue;
-
- case ESC_w:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
- continue;
-
- case ESC_W:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
- continue;
-
- /* Perl 5.004 onwards omits VT from \s, but we must preserve it
- if it was previously set by something earlier in the character
- class. */
-
- case ESC_s:
- classbits[0] |= cbits[cbit_space];
- classbits[1] |= cbits[cbit_space+1] & ~0x08;
- for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
- continue;
-
- case ESC_S:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
- classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
- continue;
-
- case ESC_h:
- SETBIT(classbits, 0x09); /* VT */
- SETBIT(classbits, 0x20); /* SPACE */
- SETBIT(classbits, 0xa0); /* NSBP */
-#ifndef COMPILE_PCRE8
- xclass = TRUE;
- *class_uchardata++ = XCL_SINGLE;
- *class_uchardata++ = 0x1680;
- *class_uchardata++ = XCL_SINGLE;
- *class_uchardata++ = 0x180e;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x2000;
- *class_uchardata++ = 0x200a;
- *class_uchardata++ = XCL_SINGLE;
- *class_uchardata++ = 0x202f;
- *class_uchardata++ = XCL_SINGLE;
- *class_uchardata++ = 0x205f;
- *class_uchardata++ = XCL_SINGLE;
- *class_uchardata++ = 0x3000;
-#elif defined SUPPORT_UTF
- if (utf)
- {
- xclass = TRUE;
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata);
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata);
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata);
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata);
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata);
- }
-#endif
- continue;
-
- case ESC_H:
- for (c = 0; c < 32; c++)
- {
- int x = 0xff;
- switch (c)
- {
- case 0x09/8: x ^= 1 << (0x09%8); break;
- case 0x20/8: x ^= 1 << (0x20%8); break;
- case 0xa0/8: x ^= 1 << (0xa0%8); break;
- default: break;
- }
- classbits[c] |= x;
- }
-#ifndef COMPILE_PCRE8
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x0100;
- *class_uchardata++ = 0x167f;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x1681;
- *class_uchardata++ = 0x180d;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x180f;
- *class_uchardata++ = 0x1fff;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x200b;
- *class_uchardata++ = 0x202e;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x2030;
- *class_uchardata++ = 0x205e;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x2060;
- *class_uchardata++ = 0x2fff;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x3001;
-#ifdef SUPPORT_UTF
- if (utf)
- class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
- else
-#endif
- *class_uchardata++ = 0xffff;
-#elif defined SUPPORT_UTF
- if (utf)
- {
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
- }
-#endif
- continue;
-
- case ESC_v:
- SETBIT(classbits, 0x0a); /* LF */
- SETBIT(classbits, 0x0b); /* VT */
- SETBIT(classbits, 0x0c); /* FF */
- SETBIT(classbits, 0x0d); /* CR */
- SETBIT(classbits, 0x85); /* NEL */
-#ifndef COMPILE_PCRE8
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x2028;
- *class_uchardata++ = 0x2029;
-#elif defined SUPPORT_UTF
- if (utf)
- {
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata);
- }
-#endif
- continue;
-
- case ESC_V:
- for (c = 0; c < 32; c++)
- {
- int x = 0xff;
- switch (c)
- {
- case 0x0a/8: x ^= 1 << (0x0a%8);
- x ^= 1 << (0x0b%8);
- x ^= 1 << (0x0c%8);
- x ^= 1 << (0x0d%8);
- break;
- case 0x85/8: x ^= 1 << (0x85%8); break;
- default: break;
- }
- classbits[c] |= x;
- }
-
-#ifndef COMPILE_PCRE8
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x0100;
- *class_uchardata++ = 0x2027;
- *class_uchardata++ = XCL_RANGE;
- *class_uchardata++ = 0x202a;
-#ifdef SUPPORT_UTF
- if (utf)
- class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
- else
-#endif
- *class_uchardata++ = 0xffff;
-#elif defined SUPPORT_UTF
- if (utf)
- {
- xclass = TRUE;
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata);
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata);
- class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
- }
-#endif
- continue;
-
-#ifdef SUPPORT_UCP
- case ESC_p:
- case ESC_P:
- {
- BOOL negated;
- int pdata;
- int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
- if (ptype < 0) goto FAILED;
- xclass = TRUE;
- *class_uchardata++ = ((-c == ESC_p) != negated)?
- XCL_PROP : XCL_NOTPROP;
- *class_uchardata++ = ptype;
- *class_uchardata++ = pdata;
- class_has_8bitchar--; /* Undo! */
- continue;
- }
-#endif
- /* Unrecognized escapes are faulted if PCRE is running in its
- strict mode. By default, for compatibility with Perl, they are
- treated as literals. */
-
- default:
- if ((options & PCRE_EXTRA) != 0)
- {
- *errorcodeptr = ERR7;
- goto FAILED;
- }
- class_has_8bitchar--; /* Undo the speculative increase. */
- class_single_char -= 2; /* Undo the speculative increase. */
- c = *ptr; /* Get the final character and fall through */
- break;
- }
- }
-
- /* Fall through if we have a single character (c >= 0). This may be
- greater than 256. */
-
- } /* End of backslash handling */
-
- /* A single character may be followed by '-' to form a range. However,
- Perl does not permit ']' to be the end of the range. A '-' character
- at the end is treated as a literal. Perl ignores orphaned \E sequences
- entirely. The code for handling \Q and \E is messy. */
-
- CHECK_RANGE:
- while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- {
- inescq = FALSE;
- ptr += 2;
- }
-
- oldptr = ptr;
-
- /* Remember \r or \n */
-
- if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
-
- /* Check for range */
-
- if (!inescq && ptr[1] == CHAR_MINUS)
- {
- int d;
- ptr += 2;
- while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
-
- /* If we hit \Q (not followed by \E) at this point, go into escaped
- mode. */
-
- while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
- {
- ptr += 2;
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
- { ptr += 2; continue; }
- inescq = TRUE;
- break;
- }
-
- if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
- {
- ptr = oldptr;
- goto LONE_SINGLE_CHARACTER;
- }
-
-#ifdef SUPPORT_UTF
- if (utf)
- { /* Braces are required because the */
- GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
- }
- else
-#endif
- d = *ptr; /* Not UTF-8 mode */
-
- /* The second part of a range can be a single-character escape, but
- not any of the other escapes. Perl 5.6 treats a hyphen as a literal
- in such circumstances. */
-
- if (!inescq && d == CHAR_BACKSLASH)
- {
- d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
-
- /* \b is backspace; any other special means the '-' was literal */
-
- if (d < 0)
- {
- if (d == -ESC_b) d = CHAR_BS; else
- {
- ptr = oldptr;
- goto LONE_SINGLE_CHARACTER; /* A few lines below */
- }
- }
- }
-
- /* Check that the two values are in the correct order. Optimize
- one-character ranges */
-
- if (d < c)
- {
- *errorcodeptr = ERR8;
- goto FAILED;
- }
-
- if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */
-
- /* Remember \r or \n */
-
- if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
-
- /* Since we found a character range, single character optimizations
- cannot be done anymore. */
- class_single_char = 2;
-
- /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
- matching, we have to use an XCLASS with extra data items. Caseless
- matching for characters > 127 is available only if UCP support is
- available. */
-
-#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
- if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127)))
-#elif defined SUPPORT_UTF
- if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
-#elif !(defined COMPILE_PCRE8)
- if (d > 255)
-#endif
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- {
- xclass = TRUE;
-
- /* With UCP support, we can find the other case equivalents of
- the relevant characters. There may be several ranges. Optimize how
- they fit with the basic range. */
-
-#ifdef SUPPORT_UCP
-#ifndef COMPILE_PCRE8
- if (utf && (options & PCRE_CASELESS) != 0)
-#else
- if ((options & PCRE_CASELESS) != 0)
-#endif
- {
- unsigned int occ, ocd;
- unsigned int cc = c;
- unsigned int origd = d;
- while (get_othercase_range(&cc, origd, &occ, &ocd))
- {
- if (occ >= (unsigned int)c &&
- ocd <= (unsigned int)d)
- continue; /* Skip embedded ranges */
-
- if (occ < (unsigned int)c &&
- ocd >= (unsigned int)c - 1) /* Extend the basic range */
- { /* if there is overlap, */
- c = occ; /* noting that if occ < c */
- continue; /* we can't have ocd > d */
- } /* because a subrange is */
- if (ocd > (unsigned int)d &&
- occ <= (unsigned int)d + 1) /* always shorter than */
- { /* the basic range. */
- d = ocd;
- continue;
- }
-
- if (occ == ocd)
- {
- *class_uchardata++ = XCL_SINGLE;
- }
- else
- {
- *class_uchardata++ = XCL_RANGE;
- class_uchardata += PRIV(ord2utf)(occ, class_uchardata);
- }
- class_uchardata += PRIV(ord2utf)(ocd, class_uchardata);
- }
- }
-#endif /* SUPPORT_UCP */
-
- /* Now record the original range, possibly modified for UCP caseless
- overlapping ranges. */
-
- *class_uchardata++ = XCL_RANGE;
-#ifdef SUPPORT_UTF
-#ifndef COMPILE_PCRE8
- if (utf)
- {
- class_uchardata += PRIV(ord2utf)(c, class_uchardata);
- class_uchardata += PRIV(ord2utf)(d, class_uchardata);
- }
- else
- {
- *class_uchardata++ = c;
- *class_uchardata++ = d;
- }
-#else
- class_uchardata += PRIV(ord2utf)(c, class_uchardata);
- class_uchardata += PRIV(ord2utf)(d, class_uchardata);
-#endif
-#else /* SUPPORT_UTF */
- *class_uchardata++ = c;
- *class_uchardata++ = d;
-#endif /* SUPPORT_UTF */
-
- /* With UCP support, we are done. Without UCP support, there is no
- caseless matching for UTF characters > 127; we can use the bit map
- for the smaller ones. As for 16 bit characters without UTF, we
- can still use */
-
-#ifdef SUPPORT_UCP
-#ifndef COMPILE_PCRE8
- if (utf)
-#endif
- continue; /* With next character in the class */
-#endif /* SUPPORT_UCP */
-
-#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8)
- if (utf)
- {
- if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
- /* Adjust upper limit and fall through to set up the map */
- d = 127;
- }
- else
- {
- if (c > 255) continue;
- /* Adjust upper limit and fall through to set up the map */
- d = 255;
- }
-#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP)
- if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
- /* Adjust upper limit and fall through to set up the map */
- d = 127;
-#else
- if (c > 255) continue;
- /* Adjust upper limit and fall through to set up the map */
- d = 255;
-#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */
- }
-#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
-
- /* We use the bit map for 8 bit mode, or when the characters fall
- partially or entirely to [0-255] ([0-127] for UCP) ranges. */
-
- class_has_8bitchar = 1;
-
- /* We can save a bit of time by skipping this in the pre-compile. */
-
- if (lengthptr == NULL) for (; c <= d; c++)
- {
- classbits[c/8] |= (1 << (c&7));
- if ((options & PCRE_CASELESS) != 0)
- {
- int uc = cd->fcc[c]; /* flip case */
- classbits[uc/8] |= (1 << (uc&7));
- }
- }
-
- continue; /* Go get the next char in the class */
- }
-
- /* Handle a lone single character - we can get here for a normal
- non-escape char, or after \ that introduces a single character or for an
- apparent range that isn't. */
-
- LONE_SINGLE_CHARACTER:
-
- /* Only the value of 1 matters for class_single_char. */
-
- if (class_single_char < 2) class_single_char++;
-
- /* If class_charcount is 1, we saw precisely one character. As long as
- there was no use of \p or \P, in other words, no use of any XCLASS
- features, we can optimize.
-
- The optimization throws away the bit map. We turn the item into a
- 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative.
- In the positive case, it can cause firstchar to be set. Otherwise, there
- can be no first char if this item is first, whatever repeat count may
- follow. In the case of reqchar, save the previous value for reinstating. */
-
- if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- ptr++;
- zeroreqchar = reqchar;
-
- if (negate_class)
- {
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- zerofirstchar = firstchar;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT;
-#ifdef SUPPORT_UTF
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- code += PRIV(ord2utf)(c, code);
- else
-#endif
- *code++ = c;
- goto NOT_CHAR;
- }
-
- /* For a single, positive character, get the value into mcbuffer, and
- then we can handle this with the normal one-character code. */
-
-#ifdef SUPPORT_UTF
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- mclength = PRIV(ord2utf)(c, mcbuffer);
- else
-#endif
- {
- mcbuffer[0] = c;
- mclength = 1;
- }
- goto ONE_CHAR;
- } /* End of 1-char optimization */
-
- /* Handle a character that cannot go in the bit map. */
-
-#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
- if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127)))
-#elif defined SUPPORT_UTF
- if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
-#elif !(defined COMPILE_PCRE8)
- if (c > 255)
-#endif
-
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- {
- xclass = TRUE;
- *class_uchardata++ = XCL_SINGLE;
-#ifdef SUPPORT_UTF
-#ifndef COMPILE_PCRE8
- /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
- if (!utf)
- *class_uchardata++ = c;
- else
-#endif
- class_uchardata += PRIV(ord2utf)(c, class_uchardata);
-#else /* SUPPORT_UTF */
- *class_uchardata++ = c;
-#endif /* SUPPORT_UTF */
-
-#ifdef SUPPORT_UCP
-#ifdef COMPILE_PCRE8
- if ((options & PCRE_CASELESS) != 0)
-#else
- /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
- if (utf && (options & PCRE_CASELESS) != 0)
-#endif
- {
- unsigned int othercase;
- if ((int)(othercase = UCD_OTHERCASE(c)) != c)
- {
- *class_uchardata++ = XCL_SINGLE;
- class_uchardata += PRIV(ord2utf)(othercase, class_uchardata);
- }
- }
-#endif /* SUPPORT_UCP */
-
- }
- else
-#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
-
- /* Handle a single-byte character */
- {
- class_has_8bitchar = 1;
- classbits[c/8] |= (1 << (c&7));
- if ((options & PCRE_CASELESS) != 0)
- {
- c = cd->fcc[c]; /* flip case */
- classbits[c/8] |= (1 << (c&7));
- }
- }
- }
-
- /* Loop until ']' reached. This "while" is the end of the "do" far above.
- If we are at the end of an internal nested string, revert to the outer
- string. */
-
- while (((c = *(++ptr)) != 0 ||
- (nestptr != NULL &&
- (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != 0)) &&
- (c != CHAR_RIGHT_SQUARE_BRACKET || inescq));
-
- /* Check for missing terminating ']' */
-
- if (c == 0)
- {
- *errorcodeptr = ERR6;
- goto FAILED;
- }
-
- /* If this is the first thing in the branch, there can be no first char
- setting, whatever the repeat count. Any reqchar setting must remain
- unchanged after any kind of repeat. */
-
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- zerofirstchar = firstchar;
- zeroreqchar = reqchar;
-
- /* If there are characters with values > 255, we have to compile an
- extended class, with its own opcode, unless there was a negated special
- such as \S in the class, and PCRE_UCP is not set, because in that case all
- characters > 255 are in the class, so any that were explicitly given as
- well can be ignored. If (when there are explicit characters > 255 that must
- be listed) there are no characters < 256, we can omit the bitmap in the
- actual compiled code. */
-
-#ifdef SUPPORT_UTF
- if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
-#elif !defined COMPILE_PCRE8
- if (xclass && !should_flip_negation)
-#endif
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- {
- *class_uchardata++ = XCL_END; /* Marks the end of extra data */
- *code++ = OP_XCLASS;
- code += LINK_SIZE;
- *code = negate_class? XCL_NOT:0;
-
- /* If the map is required, move up the extra data to make room for it;
- otherwise just move the code pointer to the end of the extra data. */
-
- if (class_has_8bitchar > 0)
- {
- *code++ |= XCL_MAP;
- memmove(code + (32 / sizeof(pcre_uchar)), code,
- IN_UCHARS(class_uchardata - code));
- memcpy(code, classbits, 32);
- code = class_uchardata + (32 / sizeof(pcre_uchar));
- }
- else code = class_uchardata;
-
- /* Now fill in the complete length of the item */
-
- PUT(previous, 1, (int)(code - previous));
- break; /* End of class handling */
- }
-#endif
-
- /* If there are no characters > 255, or they are all to be included or
- excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
- whole class was negated and whether there were negative specials such as \S
- (non-UCP) in the class. Then copy the 32-byte map into the code vector,
- negating it if necessary. */
-
- *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
- if (lengthptr == NULL) /* Save time in the pre-compile phase */
- {
- if (negate_class)
- for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
- memcpy(code, classbits, 32);
- }
- code += 32 / sizeof(pcre_uchar);
- NOT_CHAR:
- break;
-
-
- /* ===================================================================*/
- /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
- has been tested above. */
-
- case CHAR_LEFT_CURLY_BRACKET:
- if (!is_quantifier) goto NORMAL_CHAR;
- ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
- if (*errorcodeptr != 0) goto FAILED;
- goto REPEAT;
-
- case CHAR_ASTERISK:
- repeat_min = 0;
- repeat_max = -1;
- goto REPEAT;
-
- case CHAR_PLUS:
- repeat_min = 1;
- repeat_max = -1;
- goto REPEAT;
-
- case CHAR_QUESTION_MARK:
- repeat_min = 0;
- repeat_max = 1;
-
- REPEAT:
- if (previous == NULL)
- {
- *errorcodeptr = ERR9;
- goto FAILED;
- }
-
- if (repeat_min == 0)
- {
- firstchar = zerofirstchar; /* Adjust for zero repeat */
- reqchar = zeroreqchar; /* Ditto */
- }
-
- /* Remember whether this is a variable length repeat */
-
- reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
-
- op_type = 0; /* Default single-char op codes */
- possessive_quantifier = FALSE; /* Default not possessive quantifier */
-
- /* Save start of previous item, in case we have to move it up in order to
- insert something before it. */
-
- tempcode = previous;
-
- /* If the next character is '+', we have a possessive quantifier. This
- implies greediness, whatever the setting of the PCRE_UNGREEDY option.
- If the next character is '?' this is a minimizing repeat, by default,
- but if PCRE_UNGREEDY is set, it works the other way round. We change the
- repeat type to the non-default. */
-
- if (ptr[1] == CHAR_PLUS)
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- ptr++;
- }
- else if (ptr[1] == CHAR_QUESTION_MARK)
- {
- repeat_type = greedy_non_default;
- ptr++;
- }
- else repeat_type = greedy_default;
-
- /* If previous was a recursion call, wrap it in atomic brackets so that
- previous becomes the atomic group. All recursions were so wrapped in the
- past, but it no longer happens for non-repeated recursions. In fact, the
- repeated ones could be re-implemented independently so as not to need this,
- but for the moment we rely on the code for repeating groups. */
-
- if (*previous == OP_RECURSE)
- {
- memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE));
- *previous = OP_ONCE;
- PUT(previous, 1, 2 + 2*LINK_SIZE);
- previous[2 + 2*LINK_SIZE] = OP_KET;
- PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
- code += 2 + 2 * LINK_SIZE;
- length_prevgroup = 3 + 3*LINK_SIZE;
-
- /* When actually compiling, we need to check whether this was a forward
- reference, and if so, adjust the offset. */
-
- if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
- {
- int offset = GET(cd->hwm, -LINK_SIZE);
- if (offset == previous + 1 - cd->start_code)
- PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
- }
- }
-
- /* Now handle repetition for the different types of item. */
-
- /* If previous was a character or negated character match, abolish the item
- and generate a repeat item instead. If a char item has a minimum of more
- than one, ensure that it is set in reqchar - it might not be if a sequence
- such as x{3} is the first thing in a branch because the x will have gone
- into firstchar instead. */
-
- if (*previous == OP_CHAR || *previous == OP_CHARI
- || *previous == OP_NOT || *previous == OP_NOTI)
- {
- switch (*previous)
- {
- default: /* Make compiler happy. */
- case OP_CHAR: op_type = OP_STAR - OP_STAR; break;
- case OP_CHARI: op_type = OP_STARI - OP_STAR; break;
- case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break;
- case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break;
- }
-
- /* Deal with UTF characters that take up more than one character. It's
- easier to write this out separately than try to macrify it. Use c to
- hold the length of the character in bytes, plus UTF_LENGTH to flag that
- it's a length rather than a small character. */
-
-#ifdef SUPPORT_UTF
- if (utf && NOT_FIRSTCHAR(code[-1]))
- {
- pcre_uchar *lastchar = code - 1;
- BACKCHAR(lastchar);
- c = (int)(code - lastchar); /* Length of UTF-8 character */
- memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */
- c |= UTF_LENGTH; /* Flag c as a length */
- }
- else
-#endif /* SUPPORT_UTF */
-
- /* Handle the case of a single character - either with no UTF support, or
- with UTF disabled, or for a single character UTF character. */
- {
- c = code[-1];
- if (*previous <= OP_CHARI && repeat_min > 1)
- reqchar = c | req_caseopt | cd->req_varyopt;
- }
-
- /* If the repetition is unlimited, it pays to see if the next thing on
- the line is something that cannot possibly match this character. If so,
- automatically possessifying this item gains some performance in the case
- where the match fails. */
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
- }
-
- /* If previous was a character type match (\d or similar), abolish it and
- create a suitable repeat item. The code is shared with single-character
- repeats by setting op_type to add a suitable offset into repeat_type. Note
- the the Unicode property types will be present only when SUPPORT_UCP is
- defined, but we don't wrap the little bits of code here because it just
- makes it horribly messy. */
-
- else if (*previous < OP_EODN)
- {
- pcre_uchar *oldcode;
- int prop_type, prop_value;
- op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
- c = *previous;
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- OUTPUT_SINGLE_REPEAT:
- if (*previous == OP_PROP || *previous == OP_NOTPROP)
- {
- prop_type = previous[1];
- prop_value = previous[2];
- }
- else prop_type = prop_value = -1;
-
- oldcode = code;
- code = previous; /* Usually overwrite previous item */
-
- /* If the maximum is zero then the minimum must also be zero; Perl allows
- this case, so we do too - by simply omitting the item altogether. */
-
- if (repeat_max == 0) goto END_REPEAT;
-
- /*--------------------------------------------------------------------*/
- /* This code is obsolete from release 8.00; the restriction was finally
- removed: */
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
- /*--------------------------------------------------------------------*/
-
- /* Combine the op_type with the repeat_type */
-
- repeat_type += op_type;
-
- /* A minimum of zero is handled either as the special case * or ?, or as
- an UPTO, with the maximum given. */
-
- if (repeat_min == 0)
- {
- if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
- else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* A repeat minimum of 1 is optimized into some special cases. If the
- maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
- left in place and, if the maximum is greater than 1, we use OP_UPTO with
- one less than the maximum. */
-
- else if (repeat_min == 1)
- {
- if (repeat_max == -1)
- *code++ = OP_PLUS + repeat_type;
- else
- {
- code = oldcode; /* leave previous item in place */
- if (repeat_max == 1) goto END_REPEAT;
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max - 1);
- }
- }
-
- /* The case {n,n} is just an EXACT, while the general case {n,m} is
- handled as an EXACT followed by an UPTO. */
-
- else
- {
- *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
- PUT2INC(code, 0, repeat_min);
-
- /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
- we have to insert the character for the previous code. For a repeated
- Unicode property match, there are two extra bytes that define the
- required property. In UTF-8 mode, long characters have their length in
- c, with the UTF_LENGTH bit as a flag. */
-
- if (repeat_max < 0)
- {
-#ifdef SUPPORT_UTF
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- {
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- }
- *code++ = OP_STAR + repeat_type;
- }
-
- /* Else insert an UPTO if the max is greater than the min, again
- preceded by the character, for the previously inserted code. If the
- UPTO is just for 1 instance, we can use QUERY instead. */
-
- else if (repeat_max != repeat_min)
- {
-#ifdef SUPPORT_UTF
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- repeat_max -= repeat_min;
-
- if (repeat_max == 1)
- {
- *code++ = OP_QUERY + repeat_type;
- }
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
- }
-
- /* The character or character type itself comes last in all cases. */
-
-#ifdef SUPPORT_UTF
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
-
- /* For a repeated Unicode property match, there are two extra bytes that
- define the required property. */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
-#endif
- }
-
- /* If previous was a character class or a back reference, we put the repeat
- stuff after it, but just skip the item if the repeat was {0,0}. */
-
- else if (*previous == OP_CLASS ||
- *previous == OP_NCLASS ||
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- *previous == OP_XCLASS ||
-#endif
- *previous == OP_REF ||
- *previous == OP_REFI)
- {
- if (repeat_max == 0)
- {
- code = previous;
- goto END_REPEAT;
- }
-
- /*--------------------------------------------------------------------*/
- /* This code is obsolete from release 8.00; the restriction was finally
- removed: */
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
- /*--------------------------------------------------------------------*/
-
- if (repeat_min == 0 && repeat_max == -1)
- *code++ = OP_CRSTAR + repeat_type;
- else if (repeat_min == 1 && repeat_max == -1)
- *code++ = OP_CRPLUS + repeat_type;
- else if (repeat_min == 0 && repeat_max == 1)
- *code++ = OP_CRQUERY + repeat_type;
- else
- {
- *code++ = OP_CRRANGE + repeat_type;
- PUT2INC(code, 0, repeat_min);
- if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* If previous was a bracket group, we may have to replicate it in certain
- cases. Note that at this point we can encounter only the "basic" bracket
- opcodes such as BRA and CBRA, as this is the place where they get converted
- into the more special varieties such as BRAPOS and SBRA. A test for >=
- OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
- ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow
- repetition of assertions, but now it does, for Perl compatibility. */
-
- else if (*previous >= OP_ASSERT && *previous <= OP_COND)
- {
- int i;
- int len = (int)(code - previous);
- pcre_uchar *bralink = NULL;
- pcre_uchar *brazeroptr = NULL;
-
- /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so
- we just ignore the repeat. */
-
- if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
- goto END_REPEAT;
-
- /* There is no sense in actually repeating assertions. The only potential
- use of repetition is in cases when the assertion is optional. Therefore,
- if the minimum is greater than zero, just ignore the repeat. If the
- maximum is not not zero or one, set it to 1. */
-
- if (*previous < OP_ONCE) /* Assertion */
- {
- if (repeat_min > 0) goto END_REPEAT;
- if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
- }
-
- /* The case of a zero minimum is special because of the need to stick
- OP_BRAZERO in front of it, and because the group appears once in the
- data, whereas in other cases it appears the minimum number of times. For
- this reason, it is simplest to treat this case separately, as otherwise
- the code gets far too messy. There are several special subcases when the
- minimum is zero. */
-
- if (repeat_min == 0)
- {
- /* If the maximum is also zero, we used to just omit the group from the
- output altogether, like this:
-
- ** if (repeat_max == 0)
- ** {
- ** code = previous;
- ** goto END_REPEAT;
- ** }
-
- However, that fails when a group or a subgroup within it is referenced
- as a subroutine from elsewhere in the pattern, so now we stick in
- OP_SKIPZERO in front of it so that it is skipped on execution. As we
- don't have a list of which groups are referenced, we cannot do this
- selectively.
-
- If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
- and do no more at this point. However, we do need to adjust any
- OP_RECURSE calls inside the group that refer to the group itself or any
- internal or forward referenced group, because the offset is from the
- start of the whole regex. Temporarily terminate the pattern while doing
- this. */
-
- if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
- {
- *code = OP_END;
- adjust_recurse(previous, 1, utf, cd, save_hwm);
- memmove(previous + 1, previous, IN_UCHARS(len));
- code++;
- if (repeat_max == 0)
- {
- *previous++ = OP_SKIPZERO;
- goto END_REPEAT;
- }
- brazeroptr = previous; /* Save for possessive optimizing */
- *previous++ = OP_BRAZERO + repeat_type;
- }
-
- /* If the maximum is greater than 1 and limited, we have to replicate
- in a nested fashion, sticking OP_BRAZERO before each set of brackets.
- The first one has to be handled carefully because it's the original
- copy, which has to be moved up. The remainder can be handled by code
- that is common with the non-zero minimum case below. We have to
- adjust the value or repeat_max, since one less copy is required. Once
- again, we may have to adjust any OP_RECURSE calls inside the group. */
-
- else
- {
- int offset;
- *code = OP_END;
- adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
- memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
- code += 2 + LINK_SIZE;
- *previous++ = OP_BRAZERO + repeat_type;
- *previous++ = OP_BRA;
-
- /* We chain together the bracket offset fields that have to be
- filled in later when the ends of the brackets are reached. */
-
- offset = (bralink == NULL)? 0 : (int)(previous - bralink);
- bralink = previous;
- PUTINC(previous, 0, offset);
- }
-
- repeat_max--;
- }
-
- /* If the minimum is greater than zero, replicate the group as many
- times as necessary, and adjust the maximum to the number of subsequent
- copies that we need. If we set a first char from the group, and didn't
- set a required char, copy the latter from the former. If there are any
- forward reference subroutine calls in the group, there will be entries on
- the workspace list; replicate these with an appropriate increment. */
-
- else
- {
- if (repeat_min > 1)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. Do some paranoid checks for
- potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
- integer type when available, otherwise double. */
-
- if (lengthptr != NULL)
- {
- int delta = (repeat_min - 1)*length_prevgroup;
- if ((INT64_OR_DOUBLE)(repeat_min - 1)*
- (INT64_OR_DOUBLE)length_prevgroup >
- (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real. If there is a set first byte for
- the group, and we have not yet set a "required byte", set it. Make
- sure there is enough workspace for copying forward references before
- doing the copy. */
-
- else
- {
- if (groupsetfirstchar && reqchar < 0) reqchar = firstchar;
-
- for (i = 1; i < repeat_min; i++)
- {
- pcre_uchar *hc;
- pcre_uchar *this_hwm = cd->hwm;
- memcpy(code, previous, IN_UCHARS(len));
-
- while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
- {
- int save_offset = save_hwm - cd->start_workspace;
- int this_offset = this_hwm - cd->start_workspace;
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
- }
-
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len);
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
- }
- }
-
- if (repeat_max > 0) repeat_max -= repeat_min;
- }
-
- /* This code is common to both the zero and non-zero minimum cases. If
- the maximum is limited, it replicates the group in a nested fashion,
- remembering the bracket starts on a stack. In the case of a zero minimum,
- the first one was set up above. In all cases the repeat_max now specifies
- the number of additional copies needed. Again, we must remember to
- replicate entries on the forward reference list. */
-
- if (repeat_max >= 0)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. For each repetition we must add 1
- to the length for BRAZERO and for all but the last repetition we must
- add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
- paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
- a 64-bit integer type when available, otherwise double. */
-
- if (lengthptr != NULL && repeat_max > 0)
- {
- int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
- 2 - 2*LINK_SIZE; /* Last one doesn't nest */
- if ((INT64_OR_DOUBLE)repeat_max *
- (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
- > (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real */
-
- else for (i = repeat_max - 1; i >= 0; i--)
- {
- pcre_uchar *hc;
- pcre_uchar *this_hwm = cd->hwm;
-
- *code++ = OP_BRAZERO + repeat_type;
-
- /* All but the final copy start a new nesting, maintaining the
- chain of brackets outstanding. */
-
- if (i != 0)
- {
- int offset;
- *code++ = OP_BRA;
- offset = (bralink == NULL)? 0 : (int)(code - bralink);
- bralink = code;
- PUTINC(code, 0, offset);
- }
-
- memcpy(code, previous, IN_UCHARS(len));
-
- /* Ensure there is enough workspace for forward references before
- copying them. */
-
- while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
- {
- int save_offset = save_hwm - cd->start_workspace;
- int this_offset = this_hwm - cd->start_workspace;
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
- }
-
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
-
- /* Now chain through the pending brackets, and fill in their length
- fields (which are holding the chain links pro tem). */
-
- while (bralink != NULL)
- {
- int oldlinkoffset;
- int offset = (int)(code - bralink + 1);
- pcre_uchar *bra = code - offset;
- oldlinkoffset = GET(bra, 1);
- bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
- *code++ = OP_KET;
- PUTINC(code, 0, offset);
- PUT(bra, 1, offset);
- }
- }
-
- /* If the maximum is unlimited, set a repeater in the final copy. For
- ONCE brackets, that's all we need to do. However, possessively repeated
- ONCE brackets can be converted into non-capturing brackets, as the
- behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
- deal with possessive ONCEs specially.
-
- Otherwise, when we are doing the actual compile phase, check to see
- whether this group is one that could match an empty string. If so,
- convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
- that runtime checking can be done. [This check is also applied to ONCE
- groups at runtime, but in a different way.]
-
- Then, if the quantifier was possessive and the bracket is not a
- conditional, we convert the BRA code to the POS form, and the KET code to
- KETRPOS. (It turns out to be convenient at runtime to detect this kind of
- subpattern at both the start and at the end.) The use of special opcodes
- makes it possible to reduce greatly the stack usage in pcre_exec(). If
- the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
-
- Then, if the minimum number of matches is 1 or 0, cancel the possessive
- flag so that the default action below, of wrapping everything inside
- atomic brackets, does not happen. When the minimum is greater than 1,
- there will be earlier copies of the group, and so we still have to wrap
- the whole thing. */
-
- else
- {
- pcre_uchar *ketcode = code - 1 - LINK_SIZE;
- pcre_uchar *bracode = ketcode - GET(ketcode, 1);
-
- /* Convert possessive ONCE brackets to non-capturing */
-
- if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
- possessive_quantifier) *bracode = OP_BRA;
-
- /* For non-possessive ONCE brackets, all we need to do is to
- set the KET. */
-
- if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
- *ketcode = OP_KETRMAX + repeat_type;
-
- /* Handle non-ONCE brackets and possessive ONCEs (which have been
- converted to non-capturing above). */
-
- else
- {
- /* In the compile phase, check for empty string matching. */
-
- if (lengthptr == NULL)
- {
- pcre_uchar *scode = bracode;
- do
- {
- if (could_be_empty_branch(scode, ketcode, utf, cd))
- {
- *bracode += OP_SBRA - OP_BRA;
- break;
- }
- scode += GET(scode, 1);
- }
- while (*scode == OP_ALT);
- }
-
- /* Handle possessive quantifiers. */
-
- if (possessive_quantifier)
- {
- /* For COND brackets, we wrap the whole thing in a possessively
- repeated non-capturing bracket, because we have not invented POS
- versions of the COND opcodes. Because we are moving code along, we
- must ensure that any pending recursive references are updated. */
-
- if (*bracode == OP_COND || *bracode == OP_SCOND)
- {
- int nlen = (int)(code - bracode);
- *code = OP_END;
- adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
- memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
- code += 1 + LINK_SIZE;
- nlen += 1 + LINK_SIZE;
- *bracode = OP_BRAPOS;
- *code++ = OP_KETRPOS;
- PUTINC(code, 0, nlen);
- PUT(bracode, 1, nlen);
- }
-
- /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
-
- else
- {
- *bracode += 1; /* Switch to xxxPOS opcodes */
- *ketcode = OP_KETRPOS;
- }
-
- /* If the minimum is zero, mark it as possessive, then unset the
- possessive flag when the minimum is 0 or 1. */
-
- if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
- if (repeat_min < 2) possessive_quantifier = FALSE;
- }
-
- /* Non-possessive quantifier */
-
- else *ketcode = OP_KETRMAX + repeat_type;
- }
- }
- }
-
- /* If previous is OP_FAIL, it was generated by an empty class [] in
- JavaScript mode. The other ways in which OP_FAIL can be generated, that is
- by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
- error above. We can just ignore the repeat in JS case. */
-
- else if (*previous == OP_FAIL) goto END_REPEAT;
-
- /* Else there's some kind of shambles */
-
- else
- {
- *errorcodeptr = ERR11;
- goto FAILED;
- }
-
- /* If the character following a repeat is '+', or if certain optimization
- tests above succeeded, possessive_quantifier is TRUE. For some opcodes,
- there are special alternative opcodes for this case. For anything else, we
- wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+'
- notation is just syntactic sugar, taken from Sun's Java package, but the
- special opcodes can optimize it.
-
- Some (but not all) possessively repeated subpatterns have already been
- completely handled in the code just above. For them, possessive_quantifier
- is always FALSE at this stage.
-
- Note that the repeated item starts at tempcode, not at previous, which
- might be the first part of a string whose (former) last char we repeated.
-
- Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
- an 'upto' may follow. We skip over an 'exact' item, and then test the
- length of what remains before proceeding. */
-
- if (possessive_quantifier)
- {
- int len;
-
- if (*tempcode == OP_TYPEEXACT)
- tempcode += PRIV(OP_lengths)[*tempcode] +
- ((tempcode[1 + IMM2_SIZE] == OP_PROP
- || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
-
- else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
- {
- tempcode += PRIV(OP_lengths)[*tempcode];
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(tempcode[-1]))
- tempcode += GET_EXTRALEN(tempcode[-1]);
-#endif
- }
-
- len = (int)(code - tempcode);
- if (len > 0) switch (*tempcode)
- {
- case OP_STAR: *tempcode = OP_POSSTAR; break;
- case OP_PLUS: *tempcode = OP_POSPLUS; break;
- case OP_QUERY: *tempcode = OP_POSQUERY; break;
- case OP_UPTO: *tempcode = OP_POSUPTO; break;
-
- case OP_STARI: *tempcode = OP_POSSTARI; break;
- case OP_PLUSI: *tempcode = OP_POSPLUSI; break;
- case OP_QUERYI: *tempcode = OP_POSQUERYI; break;
- case OP_UPTOI: *tempcode = OP_POSUPTOI; break;
-
- case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
- case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
- case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
- case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
-
- case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break;
- case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break;
- case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break;
- case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break;
-
- case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
- case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
- case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
- case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
-
- /* Because we are moving code along, we must ensure that any
- pending recursive references are updated. */
-
- default:
- *code = OP_END;
- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
- memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
- code += 1 + LINK_SIZE;
- len += 1 + LINK_SIZE;
- tempcode[0] = OP_ONCE;
- *code++ = OP_KET;
- PUTINC(code, 0, len);
- PUT(tempcode, 1, len);
- break;
- }
- }
-
- /* In all case we no longer have a previous item. We also set the
- "follows varying string" flag for subsequently encountered reqchars if
- it isn't already set and we have just passed a varying length item. */
-
- END_REPEAT:
- previous = NULL;
- cd->req_varyopt |= reqvary;
- break;
-
-
- /* ===================================================================*/
- /* Start of nested parenthesized sub-expression, or comment or lookahead or
- lookbehind or option setting or condition or all the other extended
- parenthesis forms. */
-
- case CHAR_LEFT_PARENTHESIS:
- newoptions = options;
- skipbytes = 0;
- bravalue = OP_CBRA;
- save_hwm = cd->hwm;
- reset_bracount = FALSE;
-
- /* First deal with various "verbs" that can be introduced by '*'. */
-
- ptr++;
- if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
- || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
- {
- int i, namelen;
- int arglen = 0;
- const char *vn = verbnames;
- const pcre_uchar *name = ptr + 1;
- const pcre_uchar *arg = NULL;
- previous = NULL;
- ptr++;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* It appears that Perl allows any characters whatsoever, other than
- a closing parenthesis, to appear in arguments, so we no longer insist on
- letters, digits, and underscores. */
-
- if (*ptr == CHAR_COLON)
- {
- arg = ++ptr;
- while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- arglen = (int)(ptr - arg);
- if (arglen > (int)MAX_MARK)
- {
- *errorcodeptr = ERR75;
- goto FAILED;
- }
- }
-
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR60;
- goto FAILED;
- }
-
- /* Scan the table of verb names */
-
- for (i = 0; i < verbcount; i++)
- {
- if (namelen == verbs[i].len &&
- STRNCMP_UC_C8(name, vn, namelen) == 0)
- {
- /* Check for open captures before ACCEPT and convert it to
- ASSERT_ACCEPT if in an assertion. */
-
- if (verbs[i].op == OP_ACCEPT)
- {
- open_capitem *oc;
- if (arglen != 0)
- {
- *errorcodeptr = ERR59;
- goto FAILED;
- }
- cd->had_accept = TRUE;
- for (oc = cd->open_caps; oc != NULL; oc = oc->next)
- {
- *code++ = OP_CLOSE;
- PUT2INC(code, 0, oc->number);
- }
- *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
-
- /* Do not set firstchar after *ACCEPT */
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- }
-
- /* Handle other cases with/without an argument */
-
- else if (arglen == 0)
- {
- if (verbs[i].op < 0) /* Argument is mandatory */
- {
- *errorcodeptr = ERR66;
- goto FAILED;
- }
- *code = verbs[i].op;
- if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN;
- }
-
- else
- {
- if (verbs[i].op_arg < 0) /* Argument is forbidden */
- {
- *errorcodeptr = ERR59;
- goto FAILED;
- }
- *code = verbs[i].op_arg;
- if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN;
- *code++ = arglen;
- memcpy(code, arg, IN_UCHARS(arglen));
- code += arglen;
- *code++ = 0;
- }
-
- break; /* Found verb, exit loop */
- }
-
- vn += verbs[i].len + 1;
- }
-
- if (i < verbcount) continue; /* Successfully handled a verb */
- *errorcodeptr = ERR60; /* Verb not recognized */
- goto FAILED;
- }
-
- /* Deal with the extended parentheses; all are introduced by '?', and the
- appearance of any of them means that this is not a capturing group. */
-
- else if (*ptr == CHAR_QUESTION_MARK)
- {
- int i, set, unset, namelen;
- int *optset;
- const pcre_uchar *name;
- pcre_uchar *slot;
-
- switch (*(++ptr))
- {
- case CHAR_NUMBER_SIGN: /* Comment; skip to ket */
- ptr++;
- while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr == 0)
- {
- *errorcodeptr = ERR18;
- goto FAILED;
- }
- continue;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
- reset_bracount = TRUE;
- /* Fall through */
-
- /* ------------------------------------------------------------ */
- case CHAR_COLON: /* Non-capturing bracket */
- bravalue = OP_BRA;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_LEFT_PARENTHESIS:
- bravalue = OP_COND; /* Conditional group */
-
- /* A condition can be an assertion, a number (referring to a numbered
- group), a name (referring to a named group), or 'R', referring to
- recursion. R<digits> and R&name are also permitted for recursion tests.
-
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
-
- There are two unfortunate ambiguities, caused by history. (a) 'R' can
- be the recursive thing or the name 'R' (and similarly for 'R' followed
- by digits), and (b) a number could be a name that consists of digits.
- In both cases, we look for a name first; if not found, we try the other
- cases. */
-
- /* For conditions that are assertions, check the syntax, and then exit
- the switch. This will take control down to where bracketed groups,
- including assertions, are processed. */
-
- if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN ||
- ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN))
- break;
-
- /* Most other conditions use OP_CREF (a couple change to OP_RREF
- below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
-
- code[1+LINK_SIZE] = OP_CREF;
- skipbytes = 1+IMM2_SIZE;
- refsign = -1;
-
- /* Check for a test for recursion in a named group. */
-
- if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
- {
- terminator = -1;
- ptr += 2;
- code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */
- }
-
- /* Check for a test for a named group's having been set, using the Perl
- syntax (?(<name>) or (?('name') */
-
- else if (ptr[1] == CHAR_LESS_THAN_SIGN)
- {
- terminator = CHAR_GREATER_THAN_SIGN;
- ptr++;
- }
- else if (ptr[1] == CHAR_APOSTROPHE)
- {
- terminator = CHAR_APOSTROPHE;
- ptr++;
- }
- else
- {
- terminator = 0;
- if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
- }
-
- /* We now expect to read a name; any thing else is an error */
-
- if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
- {
- ptr += 1; /* To get the right offset */
- *errorcodeptr = ERR28;
- goto FAILED;
- }
-
- /* Read the name, but also get it as a number if it's all digits */
-
- recno = 0;
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
- {
- if (recno >= 0)
- recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1;
- ptr++;
- }
- namelen = (int)(ptr - name);
-
- if ((terminator > 0 && *ptr++ != terminator) ||
- *ptr++ != CHAR_RIGHT_PARENTHESIS)
- {
- ptr--; /* Error offset */
- *errorcodeptr = ERR26;
- goto FAILED;
- }
-
- /* Do no further checking in the pre-compile phase. */
-
- if (lengthptr != NULL) break;
-
- /* In the real compile we do the work of looking for the actual
- reference. If the string started with "+" or "-" we require the rest to
- be digits, in which case recno will be set. */
-
- if (refsign > 0)
- {
- if (recno <= 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = (refsign == CHAR_MINUS)?
- cd->bracount - recno + 1 : recno +cd->bracount;
- if (recno <= 0 || recno > cd->final_bracount)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- PUT2(code, 2+LINK_SIZE, recno);
- break;
- }
-
- /* Otherwise (did not start with "+" or "-"), start by looking for the
- name. If we find a name, add one to the opcode to change OP_CREF or
- OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
- except they record that the reference was originally to a name. The
- information is used to check duplicate names. */
-
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break;
- slot += cd->name_entry_size;
- }
-
- /* Found a previous named subpattern */
-
- if (i < cd->names_found)
- {
- recno = GET2(slot, 0);
- PUT2(code, 2+LINK_SIZE, recno);
- code[1+LINK_SIZE]++;
- }
-
- /* Search the pattern for a forward reference */
-
- else if ((i = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) > 0)
- {
- PUT2(code, 2+LINK_SIZE, i);
- code[1+LINK_SIZE]++;
- }
-
- /* If terminator == 0 it means that the name followed directly after
- the opening parenthesis [e.g. (?(abc)...] and in this case there are
- some further alternatives to try. For the cases where terminator != 0
- [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
- now checked all the possibilities, so give an error. */
-
- else if (terminator != 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
-
- /* Check for (?(R) for recursion. Allow digits after R to specify a
- specific group number. */
-
- else if (*name == CHAR_R)
- {
- recno = 0;
- for (i = 1; i < namelen; i++)
- {
- if (!IS_DIGIT(name[i]))
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- recno = recno * 10 + name[i] - CHAR_0;
- }
- if (recno == 0) recno = RREF_ANY;
- code[1+LINK_SIZE] = OP_RREF; /* Change test type */
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Similarly, check for the (?(DEFINE) "condition", which is always
- false. */
-
- else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0)
- {
- code[1+LINK_SIZE] = OP_DEF;
- skipbytes = 1;
- }
-
- /* Check for the "name" actually being a subpattern number. We are
- in the second pass here, so final_bracount is set. */
-
- else if (recno > 0 && recno <= cd->final_bracount)
- {
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Either an unidentified subpattern, or a reference to (?(0) */
-
- else
- {
- *errorcodeptr = (recno == 0)? ERR35: ERR15;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_EQUALS_SIGN: /* Positive lookahead */
- bravalue = OP_ASSERT;
- cd->assert_depth += 1;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
- ptr++;
- if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
- {
- *code++ = OP_FAIL;
- previous = NULL;
- continue;
- }
- bravalue = OP_ASSERT_NOT;
- cd->assert_depth += 1;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */
- switch (ptr[1])
- {
- case CHAR_EQUALS_SIGN: /* Positive lookbehind */
- bravalue = OP_ASSERTBACK;
- cd->assert_depth += 1;
- ptr += 2;
- break;
-
- case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */
- bravalue = OP_ASSERTBACK_NOT;
- cd->assert_depth += 1;
- ptr += 2;
- break;
-
- default: /* Could be name define, else bad */
- if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
- goto DEFINE_NAME;
- ptr++; /* Correct offset for error */
- *errorcodeptr = ERR24;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_GREATER_THAN_SIGN: /* One-time brackets */
- bravalue = OP_ONCE;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_C: /* Callout - may be followed by digits; */
- previous_callout = code; /* Save for later completion */
- after_manual_callout = 1; /* Skip one item before completing */
- *code++ = OP_CALLOUT;
- {
- int n = 0;
- ptr++;
- while(IS_DIGIT(*ptr))
- n = n * 10 + *ptr++ - CHAR_0;
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR39;
- goto FAILED;
- }
- if (n > 255)
- {
- *errorcodeptr = ERR38;
- goto FAILED;
- }
- *code++ = n;
- PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
- PUT(code, LINK_SIZE, 0); /* Default length */
- code += 2 * LINK_SIZE;
- }
- previous = NULL;
- continue;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_P: /* Python-style named subpattern handling */
- if (*(++ptr) == CHAR_EQUALS_SIGN ||
- *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */
- {
- is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
- terminator = CHAR_RIGHT_PARENTHESIS;
- goto NAMED_REF_OR_RECURSE;
- }
- else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */
- {
- *errorcodeptr = ERR41;
- goto FAILED;
- }
- /* Fall through to handle (?P< as (?< is handled */
-
-
- /* ------------------------------------------------------------ */
- DEFINE_NAME: /* Come here from (?< handling */
- case CHAR_APOSTROPHE:
- {
- terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
- name = ++ptr;
-
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* In the pre-compile phase, just do a syntax check. */
-
- if (lengthptr != NULL)
- {
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (cd->names_found >= MAX_NAME_COUNT)
- {
- *errorcodeptr = ERR49;
- goto FAILED;
- }
- if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
- {
- cd->name_entry_size = namelen + IMM2_SIZE + 1;
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
- }
- }
-
- /* In the real compile, create the entry in the table, maintaining
- alphabetical order. Duplicate names for different numbers are
- permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
- number are always OK. (An existing number can be re-used if (?|
- appears in the pattern.) In either event, a duplicate name results in
- a duplicate entry in the table, even if the number is the same. This
- is because the number of names, and hence the table size, is computed
- in the pre-compile, and it affects various numbers and pointers which
- would all have to be modified, and the compiled code moved down, if
- duplicates with the same number were omitted from the table. This
- doesn't seem worth the hassle. However, *different* names for the
- same number are not permitted. */
-
- else
- {
- BOOL dupname = FALSE;
- slot = cd->name_table;
-
- for (i = 0; i < cd->names_found; i++)
- {
- int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
- if (crc == 0)
- {
- if (slot[IMM2_SIZE+namelen] == 0)
- {
- if (GET2(slot, 0) != cd->bracount + 1 &&
- (options & PCRE_DUPNAMES) == 0)
- {
- *errorcodeptr = ERR43;
- goto FAILED;
- }
- else dupname = TRUE;
- }
- else crc = -1; /* Current name is a substring */
- }
-
- /* Make space in the table and break the loop for an earlier
- name. For a duplicate or later name, carry on. We do this for
- duplicates so that in the simple case (when ?(| is not used) they
- are in order of their numbers. */
-
- if (crc < 0)
- {
- memmove(slot + cd->name_entry_size, slot,
- IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
- break;
- }
-
- /* Continue the loop for a later or duplicate name */
-
- slot += cd->name_entry_size;
- }
-
- /* For non-duplicate names, check for a duplicate number before
- adding the new name. */
-
- if (!dupname)
- {
- pcre_uchar *cslot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (cslot != slot)
- {
- if (GET2(cslot, 0) == cd->bracount + 1)
- {
- *errorcodeptr = ERR65;
- goto FAILED;
- }
- }
- else i--;
- cslot += cd->name_entry_size;
- }
- }
-
- PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
- slot[IMM2_SIZE + namelen] = 0;
- }
- }
-
- /* In both pre-compile and compile, count the number of names we've
- encountered. */
-
- cd->names_found++;
- ptr++; /* Move past > or ' */
- goto NUMBERED_GROUP;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */
- terminator = CHAR_RIGHT_PARENTHESIS;
- is_recurse = TRUE;
- /* Fall through */
-
- /* We come here from the Python syntax above that handles both
- references (?P=name) and recursion (?P>name), as well as falling
- through from the Perl recursion syntax (?&name). We also come here from
- the Perl \k<name> or \k'name' back reference syntax and the \k{name}
- .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
-
- NAMED_REF_OR_RECURSE:
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* In the pre-compile phase, do a syntax check. We used to just set
- a dummy reference number, because it was not used in the first pass.
- However, with the change of recursive back references to be atomic,
- we have to look for the number so that this state can be identified, as
- otherwise the incorrect length is computed. If it's not a backwards
- reference, the dummy number will do. */
-
- if (lengthptr != NULL)
- {
- const pcre_uchar *temp;
-
- if (namelen == 0)
- {
- *errorcodeptr = ERR62;
- goto FAILED;
- }
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
-
- /* The name table does not exist in the first pass, so we cannot
- do a simple search as in the code below. Instead, we have to scan the
- pattern to find the number. It is important that we scan it only as
- far as we have got because the syntax of named subpatterns has not
- been checked for the rest of the pattern, and find_parens() assumes
- correct syntax. In any case, it's a waste of resources to scan
- further. We stop the scan at the current point by temporarily
- adjusting the value of cd->endpattern. */
-
- temp = cd->end_pattern;
- cd->end_pattern = ptr;
- recno = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf);
- cd->end_pattern = temp;
- if (recno < 0) recno = 0; /* Forward ref; set dummy number */
- }
-
- /* In the real compile, seek the name in the table. We check the name
- first, and then check that we have reached the end of the name in the
- table. That way, if the name that is longer than any in the table,
- the comparison will fail without reading beyond the table entry. */
-
- else
- {
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 &&
- slot[IMM2_SIZE+namelen] == 0)
- break;
- slot += cd->name_entry_size;
- }
-
- if (i < cd->names_found) /* Back reference */
- {
- recno = GET2(slot, 0);
- }
- else if ((recno = /* Forward back reference */
- find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
-
- /* In both phases, we can now go to the code than handles numerical
- recursion or backreferences. */
-
- if (is_recurse) goto HANDLE_RECURSION;
- else goto HANDLE_REFERENCE;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_R: /* Recursion */
- ptr++; /* Same as (?0) */
- /* Fall through */
-
-
- /* ------------------------------------------------------------ */
- case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */
- case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
- case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
- {
- const pcre_uchar *called;
- terminator = CHAR_RIGHT_PARENTHESIS;
-
- /* Come here from the \g<...> and \g'...' code (Oniguruma
- compatibility). However, the syntax has been checked to ensure that
- the ... are a (signed) number, so that neither ERR63 nor ERR29 will
- be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
- ever be taken. */
-
- HANDLE_NUMERICAL_RECURSION:
-
- if ((refsign = *ptr) == CHAR_PLUS)
- {
- ptr++;
- if (!IS_DIGIT(*ptr))
- {
- *errorcodeptr = ERR63;
- goto FAILED;
- }
- }
- else if (refsign == CHAR_MINUS)
- {
- if (!IS_DIGIT(ptr[1]))
- goto OTHER_CHAR_AFTER_QUERY;
- ptr++;
- }
-
- recno = 0;
- while(IS_DIGIT(*ptr))
- recno = recno * 10 + *ptr++ - CHAR_0;
-
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR29;
- goto FAILED;
- }
-
- if (refsign == CHAR_MINUS)
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = cd->bracount - recno + 1;
- if (recno <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
- else if (refsign == CHAR_PLUS)
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno += cd->bracount;
- }
-
- /* Come here from code above that handles a named recursion */
-
- HANDLE_RECURSION:
-
- previous = code;
- called = cd->start_code;
-
- /* When we are actually compiling, find the bracket that is being
- referenced. Temporarily end the regex in case it doesn't exist before
- this point. If we end up with a forward reference, first check that
- the bracket does occur later so we can give the error (and position)
- now. Then remember this forward reference in the workspace so it can
- be filled in at the end. */
-
- if (lengthptr == NULL)
- {
- *code = OP_END;
- if (recno != 0)
- called = PRIV(find_bracket)(cd->start_code, utf, recno);
-
- /* Forward reference */
-
- if (called == NULL)
- {
- if (find_parens(cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0, utf) < 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
-
- /* Fudge the value of "called" so that when it is inserted as an
- offset below, what it actually inserted is the reference number
- of the group. Then remember the forward reference. */
-
- called = cd->start_code + recno;
- if (cd->hwm >= cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN)
- {
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- }
- PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
- }
-
- /* If not a forward reference, and the subpattern is still open,
- this is a recursive call. We check to see if this is a left
- recursion that could loop for ever, and diagnose that case. We
- must not, however, do this check if we are in a conditional
- subpattern because the condition might be testing for recursion in
- a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid.
- Forever loops are also detected at runtime, so those that occur in
- conditional subpatterns will be picked up then. */
-
- else if (GET(called, 1) == 0 && cond_depth <= 0 &&
- could_be_empty(called, code, bcptr, utf, cd))
- {
- *errorcodeptr = ERR40;
- goto FAILED;
- }
- }
-
- /* Insert the recursion/subroutine item. It does not have a set first
- character (relevant if it is repeated, because it will then be
- wrapped with ONCE brackets). */
-
- *code = OP_RECURSE;
- PUT(code, 1, (int)(called - cd->start_code));
- code += 1 + LINK_SIZE;
- groupsetfirstchar = FALSE;
- }
-
- /* Can't determine a first byte now */
-
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- continue;
-
-
- /* ------------------------------------------------------------ */
- default: /* Other characters: check option setting */
- OTHER_CHAR_AFTER_QUERY:
- set = unset = 0;
- optset = &set;
-
- while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
- {
- switch (*ptr++)
- {
- case CHAR_MINUS: optset = &unset; break;
-
- case CHAR_J: /* Record that it changed in the external options */
- *optset |= PCRE_DUPNAMES;
- cd->external_flags |= PCRE_JCHANGED;
- break;
-
- case CHAR_i: *optset |= PCRE_CASELESS; break;
- case CHAR_m: *optset |= PCRE_MULTILINE; break;
- case CHAR_s: *optset |= PCRE_DOTALL; break;
- case CHAR_x: *optset |= PCRE_EXTENDED; break;
- case CHAR_U: *optset |= PCRE_UNGREEDY; break;
- case CHAR_X: *optset |= PCRE_EXTRA; break;
-
- default: *errorcodeptr = ERR12;
- ptr--; /* Correct the offset */
- goto FAILED;
- }
- }
-
- /* Set up the changed option bits, but don't change anything yet. */
-
- newoptions = (options | set) & (~unset);
-
- /* If the options ended with ')' this is not the start of a nested
- group with option changes, so the options change at this level. If this
- item is right at the start of the pattern, the options can be
- abstracted and made external in the pre-compile phase, and ignored in
- the compile phase. This can be helpful when matching -- for instance in
- caseless checking of required bytes.
-
- If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
- definitely *not* at the start of the pattern because something has been
- compiled. In the pre-compile phase, however, the code pointer can have
- that value after the start, because it gets reset as code is discarded
- during the pre-compile. However, this can happen only at top level - if
- we are within parentheses, the starting BRA will still be present. At
- any parenthesis level, the length value can be used to test if anything
- has been compiled at that level. Thus, a test for both these conditions
- is necessary to ensure we correctly detect the start of the pattern in
- both phases.
-
- If we are not at the pattern start, reset the greedy defaults and the
- case value for firstchar and reqchar. */
-
- if (*ptr == CHAR_RIGHT_PARENTHESIS)
- {
- if (code == cd->start_code + 1 + LINK_SIZE &&
- (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
- {
- cd->external_options = newoptions;
- }
- else
- {
- greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
- greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
- }
-
- /* Change options at this level, and pass them back for use
- in subsequent branches. */
-
- *optionsptr = options = newoptions;
- previous = NULL; /* This item can't be repeated */
- continue; /* It is complete */
- }
-
- /* If the options ended with ':' we are heading into a nested group
- with possible change of options. Such groups are non-capturing and are
- not assertions of any kind. All we need to do is skip over the ':';
- the newoptions value is handled below. */
-
- bravalue = OP_BRA;
- ptr++;
- } /* End of switch for character following (? */
- } /* End of (? handling */
-
- /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE
- is set, all unadorned brackets become non-capturing and behave like (?:...)
- brackets. */
-
- else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
- {
- bravalue = OP_BRA;
- }
-
- /* Else we have a capturing group. */
-
- else
- {
- NUMBERED_GROUP:
- cd->bracount += 1;
- PUT2(code, 1+LINK_SIZE, cd->bracount);
- skipbytes = IMM2_SIZE;
- }
-
- /* Process nested bracketed regex. Assertions used not to be repeatable,
- but this was changed for Perl compatibility, so all kinds can now be
- repeated. We copy code into a non-register variable (tempcode) in order to
- be able to pass its address because some compilers complain otherwise. */
-
- previous = code; /* For handling repetition */
- *code = bravalue;
- tempcode = code;
- tempreqvary = cd->req_varyopt; /* Save value before bracket */
- tempbracount = cd->bracount; /* Save value before bracket */
- length_prevgroup = 0; /* Initialize for pre-compile phase */
-
- if (!compile_regex(
- newoptions, /* The complete new option state */
- &tempcode, /* Where to put code (updated) */
- &ptr, /* Input pointer (updated) */
- errorcodeptr, /* Where to put an error message */
- (bravalue == OP_ASSERTBACK ||
- bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
- reset_bracount, /* True if (?| group */
- skipbytes, /* Skip over bracket number */
- cond_depth +
- ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */
- &subfirstchar, /* For possible first char */
- &subreqchar, /* For possible last char */
- bcptr, /* Current branch chain */
- cd, /* Tables block */
- (lengthptr == NULL)? NULL : /* Actual compile phase */
- &length_prevgroup /* Pre-compile phase */
- ))
- goto FAILED;
-
- /* If this was an atomic group and there are no capturing groups within it,
- generate OP_ONCE_NC instead of OP_ONCE. */
-
- if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
- *code = OP_ONCE_NC;
-
- if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
- cd->assert_depth -= 1;
-
- /* At the end of compiling, code is still pointing to the start of the
- group, while tempcode has been updated to point past the end of the group.
- The pattern pointer (ptr) is on the bracket.
-
- If this is a conditional bracket, check that there are no more than
- two branches in the group, or just one if it's a DEFINE group. We do this
- in the real compile phase, not in the pre-pass, where the whole group may
- not be available. */
-
- if (bravalue == OP_COND && lengthptr == NULL)
- {
- pcre_uchar *tc = code;
- int condcount = 0;
-
- do {
- condcount++;
- tc += GET(tc,1);
- }
- while (*tc != OP_KET);
-
- /* A DEFINE group is never obeyed inline (the "condition" is always
- false). It must have only one branch. */
-
- if (code[LINK_SIZE+1] == OP_DEF)
- {
- if (condcount > 1)
- {
- *errorcodeptr = ERR54;
- goto FAILED;
- }
- bravalue = OP_DEF; /* Just a flag to suppress char handling below */
- }
-
- /* A "normal" conditional group. If there is just one branch, we must not
- make use of its firstchar or reqchar, because this is equivalent to an
- empty second branch. */
-
- else
- {
- if (condcount > 2)
- {
- *errorcodeptr = ERR27;
- goto FAILED;
- }
- if (condcount == 1) subfirstchar = subreqchar = REQ_NONE;
- }
- }
-
- /* Error if hit end of pattern */
-
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR14;
- goto FAILED;
- }
-
- /* In the pre-compile phase, update the length by the length of the group,
- less the brackets at either end. Then reduce the compiled code to just a
- set of non-capturing brackets so that it doesn't use much memory if it is
- duplicated by a quantifier.*/
-
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
- code++; /* This already contains bravalue */
- PUTINC(code, 0, 1 + LINK_SIZE);
- *code++ = OP_KET;
- PUTINC(code, 0, 1 + LINK_SIZE);
- break; /* No need to waste time with special character handling */
- }
-
- /* Otherwise update the main code pointer to the end of the group. */
-
- code = tempcode;
-
- /* For a DEFINE group, required and first character settings are not
- relevant. */
-
- if (bravalue == OP_DEF) break;
-
- /* Handle updating of the required and first characters for other types of
- group. Update for normal brackets of all kinds, and conditions with two
- branches (see code above). If the bracket is followed by a quantifier with
- zero repeat, we have to back off. Hence the definition of zeroreqchar and
- zerofirstchar outside the main loop so that they can be accessed for the
- back off. */
-
- zeroreqchar = reqchar;
- zerofirstchar = firstchar;
- groupsetfirstchar = FALSE;
-
- if (bravalue >= OP_ONCE)
- {
- /* If we have not yet set a firstchar in this branch, take it from the
- subpattern, remembering that it was set here so that a repeat of more
- than one can replicate it as reqchar if necessary. If the subpattern has
- no firstchar, set "none" for the whole branch. In both cases, a zero
- repeat forces firstchar to "none". */
-
- if (firstchar == REQ_UNSET)
- {
- if (subfirstchar >= 0)
- {
- firstchar = subfirstchar;
- groupsetfirstchar = TRUE;
- }
- else firstchar = REQ_NONE;
- zerofirstchar = REQ_NONE;
- }
-
- /* If firstchar was previously set, convert the subpattern's firstchar
- into reqchar if there wasn't one, using the vary flag that was in
- existence beforehand. */
-
- else if (subfirstchar >= 0 && subreqchar < 0)
- subreqchar = subfirstchar | tempreqvary;
-
- /* If the subpattern set a required byte (or set a first byte that isn't
- really the first byte - see above), set it. */
-
- if (subreqchar >= 0) reqchar = subreqchar;
- }
-
- /* For a forward assertion, we take the reqchar, if set. This can be
- helpful if the pattern that follows the assertion doesn't set a different
- char. For example, it's useful for /(?=abcde).+/. We can't set firstchar
- for an assertion, however because it leads to incorrect effect for patterns
- such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead
- of a firstchar. This is overcome by a scan at the end if there's no
- firstchar, looking for an asserted first char. */
-
- else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar;
- break; /* End of processing '(' */
-
-
- /* ===================================================================*/
- /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
- are arranged to be the negation of the corresponding OP_values in the
- default case when PCRE_UCP is not set. For the back references, the values
- are ESC_REF plus the reference number. Only back references and those types
- that consume a character may be repeated. We can test for values between
- ESC_b and ESC_Z for the latter; this may have to change if any new ones are
- ever created. */
-
- case CHAR_BACKSLASH:
- tempptr = ptr;
- c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE);
- if (*errorcodeptr != 0) goto FAILED;
-
- if (c < 0)
- {
- if (-c == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- ptr += 2; /* avoid empty string */
- else inescq = TRUE;
- continue;
- }
-
- if (-c == ESC_E) continue; /* Perl ignores an orphan \E */
-
- /* For metasequences that actually match a character, we disable the
- setting of a first character if it hasn't already been set. */
-
- if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
- firstchar = REQ_NONE;
-
- /* Set values to reset to if this is followed by a zero repeat. */
-
- zerofirstchar = firstchar;
- zeroreqchar = reqchar;
-
- /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
- is a subroutine call by number (Oniguruma syntax). In fact, the value
- -ESC_g is returned only for these cases. So we don't need to check for <
- or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
- -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
- that is a synonym for a named back reference). */
-
- if (-c == ESC_g)
- {
- const pcre_uchar *p;
- save_hwm = cd->hwm; /* Normally this is set when '(' is read */
- terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
-
- /* These two statements stop the compiler for warning about possibly
- unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
- fact, because we actually check for a number below, the paths that
- would actually be in error are never taken. */
-
- skipbytes = 0;
- reset_bracount = FALSE;
-
- /* Test for a name */
-
- if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
- {
- BOOL is_a_number = TRUE;
- for (p = ptr + 1; *p != 0 && *p != terminator; p++)
- {
- if (!MAX_255(*p)) { is_a_number = FALSE; break; }
- if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;
- if ((cd->ctypes[*p] & ctype_word) == 0) break;
- }
- if (*p != terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- if (is_a_number)
- {
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
- is_recurse = TRUE;
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Test a signed number in angle brackets or quotes. */
-
- p = ptr + 2;
- while (IS_DIGIT(*p)) p++;
- if (*p != terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
-
- /* \k<name> or \k'name' is a back reference by name (Perl syntax).
- We also support \k{name} (.NET syntax). */
-
- if (-c == ESC_k)
- {
- if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
- ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
- {
- *errorcodeptr = ERR69;
- break;
- }
- is_recurse = FALSE;
- terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
- CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Back references are handled specially; must disable firstchar if
- not set to cope with cases like (?=(\w+))\1: which would otherwise set
- ':' later. */
-
- if (-c >= ESC_REF)
- {
- open_capitem *oc;
- recno = -c - ESC_REF;
-
- HANDLE_REFERENCE: /* Come here from named backref handling */
- if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
- previous = code;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
- PUT2INC(code, 0, recno);
- cd->backref_map |= (recno < 32)? (1 << recno) : 1;
- if (recno > cd->top_backref) cd->top_backref = recno;
-
- /* Check to see if this back reference is recursive, that it, it
- is inside the group that it references. A flag is set so that the
- group can be made atomic. */
-
- for (oc = cd->open_caps; oc != NULL; oc = oc->next)
- {
- if (oc->number == recno)
- {
- oc->flag = TRUE;
- break;
- }
- }
- }
-
- /* So are Unicode property matches, if supported. */
-
-#ifdef SUPPORT_UCP
- else if (-c == ESC_P || -c == ESC_p)
- {
- BOOL negated;
- int pdata;
- int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
- if (ptype < 0) goto FAILED;
- previous = code;
- *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
- *code++ = ptype;
- *code++ = pdata;
- }
-#else
-
- /* If Unicode properties are not supported, \X, \P, and \p are not
- allowed. */
-
- else if (-c == ESC_X || -c == ESC_P || -c == ESC_p)
- {
- *errorcodeptr = ERR45;
- goto FAILED;
- }
-#endif
-
- /* For the rest (including \X when Unicode properties are supported), we
- can obtain the OP value by negating the escape value in the default
- situation when PCRE_UCP is not set. When it *is* set, we substitute
- Unicode property tests. Note that \b and \B do a one-character
- lookbehind. */
-
- else
- {
- if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0)
- cd->max_lookbehind = 1;
-#ifdef SUPPORT_UCP
- if (-c >= ESC_DU && -c <= ESC_wu)
- {
- nestptr = ptr + 1; /* Where to resume */
- ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
- }
- else
-#endif
- /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
- so that it works in DFA mode and in lookbehinds. */
-
- {
- previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
- *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c;
- }
- }
- continue;
- }
-
- /* We have a data character whose value is in c. In UTF-8 mode it may have
- a value > 127. We set its representation in the length/buffer, and then
- handle it as a data character. */
-
-#ifdef SUPPORT_UTF
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- mclength = PRIV(ord2utf)(c, mcbuffer);
- else
-#endif
-
- {
- mcbuffer[0] = c;
- mclength = 1;
- }
- goto ONE_CHAR;
-
-
- /* ===================================================================*/
- /* Handle a literal character. It is guaranteed not to be whitespace or #
- when the extended flag is set. If we are in UTF-8 mode, it may be a
- multi-byte literal character. */
-
- default:
- NORMAL_CHAR:
- mclength = 1;
- mcbuffer[0] = c;
-
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(c))
- ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
-#endif
-
- /* At this point we have the character's bytes in mcbuffer, and the length
- in mclength. When not in UTF-8 mode, the length is always 1. */
-
- ONE_CHAR:
- previous = code;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR;
- for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
-
- /* Remember if \r or \n were seen */
-
- if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
- cd->external_flags |= PCRE_HASCRORLF;
-
- /* Set the first and required bytes appropriately. If no previous first
- byte, set it from this character, but revert to none on a zero repeat.
- Otherwise, leave the firstchar value alone, and don't change it on a zero
- repeat. */
-
- if (firstchar == REQ_UNSET)
- {
- zerofirstchar = REQ_NONE;
- zeroreqchar = reqchar;
-
- /* If the character is more than one byte long, we can set firstchar
- only if it is not to be matched caselessly. */
-
- if (mclength == 1 || req_caseopt == 0)
- {
- firstchar = mcbuffer[0] | req_caseopt;
- if (mclength != 1) reqchar = code[-1] | cd->req_varyopt;
- }
- else firstchar = reqchar = REQ_NONE;
- }
-
- /* firstchar was previously set; we can set reqchar only if the length is
- 1 or the matching is caseful. */
-
- else
- {
- zerofirstchar = firstchar;
- zeroreqchar = reqchar;
- if (mclength == 1 || req_caseopt == 0)
- reqchar = code[-1] | req_caseopt | cd->req_varyopt;
- }
-
- break; /* End of literal character handling */
- }
- } /* end of big loop */
-
-
-/* Control never reaches here by falling through, only by a goto for all the
-error states. Pass back the position in the pattern so that it can be displayed
-to the user for diagnosing the error. */
-
-FAILED:
-*ptrptr = ptr;
-return FALSE;
-}
-
-
-
-
-/*************************************************
-* Compile sequence of alternatives *
-*************************************************/
-
-/* On entry, ptr is pointing past the bracket character, but on return it
-points to the closing bracket, or vertical bar, or end of string. The code
-variable is pointing at the byte into which the BRA operator has been stored.
-This function is used during the pre-compile phase when we are trying to find
-out the amount of memory needed, as well as during the real compile phase. The
-value of lengthptr distinguishes the two phases.
-
-Arguments:
- options option bits, including any changes for this subpattern
- codeptr -> the address of the current code pointer
- ptrptr -> the address of the current pattern pointer
- errorcodeptr -> pointer to error code variable
- lookbehind TRUE if this is a lookbehind assertion
- reset_bracount TRUE to reset the count for each branch
- skipbytes skip this many bytes at start (for brackets and OP_COND)
- cond_depth depth of nesting for conditional subpatterns
- firstcharptr place to put the first required character, or a negative number
- reqcharptr place to put the last required character, or a negative number
- bcptr pointer to the chain of currently open branches
- cd points to the data block with tables pointers etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
-*/
-
-static BOOL
-compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr,
- int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
- int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr,
- branch_chain *bcptr, compile_data *cd, int *lengthptr)
-{
-const pcre_uchar *ptr = *ptrptr;
-pcre_uchar *code = *codeptr;
-pcre_uchar *last_branch = code;
-pcre_uchar *start_bracket = code;
-pcre_uchar *reverse_count = NULL;
-open_capitem capitem;
-int capnumber = 0;
-pcre_int32 firstchar, reqchar;
-pcre_int32 branchfirstchar, branchreqchar;
-int length;
-int orig_bracount;
-int max_bracount;
-branch_chain bc;
-
-bc.outer = bcptr;
-bc.current_branch = code;
-
-firstchar = reqchar = REQ_UNSET;
-
-/* Accumulate the length for use in the pre-compile phase. Start with the
-length of the BRA and KET and any extra bytes that are required at the
-beginning. We accumulate in a local variable to save frequent testing of
-lenthptr for NULL. We cannot do this by looking at the value of code at the
-start and end of each alternative, because compiled items are discarded during
-the pre-compile phase so that the work space is not exceeded. */
-
-length = 2 + 2*LINK_SIZE + skipbytes;
-
-/* WARNING: If the above line is changed for any reason, you must also change
-the code that abstracts option settings at the start of the pattern and makes
-them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
-pre-compile phase to find out whether anything has yet been compiled or not. */
-
-/* If this is a capturing subpattern, add to the chain of open capturing items
-so that we can detect them if (*ACCEPT) is encountered. This is also used to
-detect groups that contain recursive back references to themselves. Note that
-only OP_CBRA need be tested here; changing this opcode to one of its variants,
-e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
-
-if (*code == OP_CBRA)
- {
- capnumber = GET2(code, 1 + LINK_SIZE);
- capitem.number = capnumber;
- capitem.next = cd->open_caps;
- capitem.flag = FALSE;
- cd->open_caps = &capitem;
- }
-
-/* Offset is set zero to mark that this bracket is still open */
-
-PUT(code, 1, 0);
-code += 1 + LINK_SIZE + skipbytes;
-
-/* Loop for each alternative branch */
-
-orig_bracount = max_bracount = cd->bracount;
-for (;;)
- {
- /* For a (?| group, reset the capturing bracket count so that each branch
- uses the same numbers. */
-
- if (reset_bracount) cd->bracount = orig_bracount;
-
- /* Set up dummy OP_REVERSE if lookbehind assertion */
-
- if (lookbehind)
- {
- *code++ = OP_REVERSE;
- reverse_count = code;
- PUTINC(code, 0, 0);
- length += 1 + LINK_SIZE;
- }
-
- /* Now compile the branch; in the pre-compile phase its length gets added
- into the length. */
-
- if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar,
- &branchreqchar, &bc, cond_depth, cd,
- (lengthptr == NULL)? NULL : &length))
- {
- *ptrptr = ptr;
- return FALSE;
- }
-
- /* Keep the highest bracket count in case (?| was used and some branch
- has fewer than the rest. */
-
- if (cd->bracount > max_bracount) max_bracount = cd->bracount;
-
- /* In the real compile phase, there is some post-processing to be done. */
-
- if (lengthptr == NULL)
- {
- /* If this is the first branch, the firstchar and reqchar values for the
- branch become the values for the regex. */
-
- if (*last_branch != OP_ALT)
- {
- firstchar = branchfirstchar;
- reqchar = branchreqchar;
- }
-
- /* If this is not the first branch, the first char and reqchar have to
- match the values from all the previous branches, except that if the
- previous value for reqchar didn't have REQ_VARY set, it can still match,
- and we set REQ_VARY for the regex. */
-
- else
- {
- /* If we previously had a firstchar, but it doesn't match the new branch,
- we have to abandon the firstchar for the regex, but if there was
- previously no reqchar, it takes on the value of the old firstchar. */
-
- if (firstchar >= 0 && firstchar != branchfirstchar)
- {
- if (reqchar < 0) reqchar = firstchar;
- firstchar = REQ_NONE;
- }
-
- /* If we (now or from before) have no firstchar, a firstchar from the
- branch becomes a reqchar if there isn't a branch reqchar. */
-
- if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0)
- branchreqchar = branchfirstchar;
-
- /* Now ensure that the reqchars match */
-
- if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY))
- reqchar = REQ_NONE;
- else reqchar |= branchreqchar; /* To "or" REQ_VARY */
- }
-
- /* If lookbehind, check that this branch matches a fixed-length string, and
- put the length into the OP_REVERSE item. Temporarily mark the end of the
- branch with OP_END. If the branch contains OP_RECURSE, the result is -3
- because there may be forward references that we can't check here. Set a
- flag to cause another lookbehind check at the end. Why not do it all at the
- end? Because common, erroneous checks are picked up here and the offset of
- the problem can be shown. */
-
- if (lookbehind)
- {
- int fixed_length;
- *code = OP_END;
- fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
- FALSE, cd);
- DPRINTF(("fixed length = %d\n", fixed_length));
- if (fixed_length == -3)
- {
- cd->check_lookbehind = TRUE;
- }
- else if (fixed_length < 0)
- {
- *errorcodeptr = (fixed_length == -2)? ERR36 :
- (fixed_length == -4)? ERR70: ERR25;
- *ptrptr = ptr;
- return FALSE;
- }
- else
- {
- if (fixed_length > cd->max_lookbehind)
- cd->max_lookbehind = fixed_length;
- PUT(reverse_count, 0, fixed_length);
- }
- }
- }
-
- /* Reached end of expression, either ')' or end of pattern. In the real
- compile phase, go back through the alternative branches and reverse the chain
- of offsets, with the field in the BRA item now becoming an offset to the
- first alternative. If there are no alternatives, it points to the end of the
- group. The length in the terminating ket is always the length of the whole
- bracketed item. Return leaving the pointer at the terminating char. */
-
- if (*ptr != CHAR_VERTICAL_LINE)
- {
- if (lengthptr == NULL)
- {
- int branch_length = (int)(code - last_branch);
- do
- {
- int prev_length = GET(last_branch, 1);
- PUT(last_branch, 1, branch_length);
- branch_length = prev_length;
- last_branch -= branch_length;
- }
- while (branch_length > 0);
- }
-
- /* Fill in the ket */
-
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
-
- /* If it was a capturing subpattern, check to see if it contained any
- recursive back references. If so, we must wrap it in atomic brackets.
- In any event, remove the block from the chain. */
-
- if (capnumber > 0)
- {
- if (cd->open_caps->flag)
- {
- memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
- IN_UCHARS(code - start_bracket));
- *start_bracket = OP_ONCE;
- code += 1 + LINK_SIZE;
- PUT(start_bracket, 1, (int)(code - start_bracket));
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
- length += 2 + 2*LINK_SIZE;
- }
- cd->open_caps = cd->open_caps->next;
- }
-
- /* Retain the highest bracket number, in case resetting was used. */
-
- cd->bracount = max_bracount;
-
- /* Set values to pass back */
-
- *codeptr = code;
- *ptrptr = ptr;
- *firstcharptr = firstchar;
- *reqcharptr = reqchar;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length)
- {
- *errorcodeptr = ERR20;
- return FALSE;
- }
- *lengthptr += length;
- }
- return TRUE;
- }
-
- /* Another branch follows. In the pre-compile phase, we can move the code
- pointer back to where it was for the start of the first branch. (That is,
- pretend that each branch is the only one.)
-
- In the real compile phase, insert an ALT node. Its length field points back
- to the previous branch while the bracket remains open. At the end the chain
- is reversed. It's done like this so that the start of the bracket has a
- zero offset until it is closed, making it possible to detect recursion. */
-
- if (lengthptr != NULL)
- {
- code = *codeptr + 1 + LINK_SIZE + skipbytes;
- length += 1 + LINK_SIZE;
- }
- else
- {
- *code = OP_ALT;
- PUT(code, 1, (int)(code - last_branch));
- bc.current_branch = last_branch = code;
- code += 1 + LINK_SIZE;
- }
-
- ptr++;
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Check for anchored expression *
-*************************************************/
-
-/* Try to find out if this is an anchored regular expression. Consider each
-alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
-all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD will
-be found, because ^ generates OP_CIRCM in that mode.
-
-We can also consider a regex to be anchored if OP_SOM starts all its branches.
-This is the code for \G, which means "match at start of match position, taking
-into account the match offset".
-
-A branch is also implicitly anchored if it starts with .* and DOTALL is set,
-because that will try the rest of the pattern at all possible matching points,
-so there is no point trying again.... er ....
-
-.... except when the .* appears inside capturing parentheses, and there is a
-subsequent back reference to those parentheses. We haven't enough information
-to catch that case precisely.
-
-At first, the best we could do was to detect when .* was in capturing brackets
-and the highest back reference was greater than or equal to that level.
-However, by keeping a bitmap of the first 31 back references, we can catch some
-of the more common cases more precisely.
-
-Arguments:
- code points to start of expression (the bracket)
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- backref_map the back reference bitmap
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_anchored(const pcre_uchar *code, unsigned int bracket_map,
- unsigned int backref_map)
-{
-do {
- const pcre_uchar *scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- int op = *scode;
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_anchored(scode, new_map, backref_map)) return FALSE;
- }
-
- /* Other brackets */
-
- else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC ||
- op == OP_COND)
- {
- if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
- }
-
- /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
- it isn't in brackets that are or may be referenced. */
-
- else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
- op == OP_TYPEPOSSTAR))
- {
- if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
- return FALSE;
- }
-
- /* Check for explicit anchoring */
-
- else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for starting with ^ or .* *
-*************************************************/
-
-/* This is called to find out if every branch starts with ^ or .* so that
-"first char" processing can be done to speed things up in multiline
-matching and for non-DOTALL patterns that start with .* (which must start at
-the beginning or after \n). As in the case of is_anchored() (see above), we
-have to take account of back references to capturing brackets that contain .*
-because in that case we can't make the assumption.
-
-Arguments:
- code points to start of expression (the bracket)
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- backref_map the back reference bitmap
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_startline(const pcre_uchar *code, unsigned int bracket_map,
- unsigned int backref_map)
-{
-do {
- const pcre_uchar *scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- int op = *scode;
-
- /* If we are at the start of a conditional assertion group, *both* the
- conditional assertion *and* what follows the condition must satisfy the test
- for start of line. Other kinds of condition fail. Note that there may be an
- auto-callout at the start of a condition. */
-
- if (op == OP_COND)
- {
- scode += 1 + LINK_SIZE;
- if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
- switch (*scode)
- {
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- return FALSE;
-
- default: /* Assertion */
- if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
- do scode += GET(scode, 1); while (*scode == OP_ALT);
- scode += 1 + LINK_SIZE;
- break;
- }
- scode = first_significant_code(scode, FALSE);
- op = *scode;
- }
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_startline(scode, new_map, backref_map)) return FALSE;
- }
-
- /* Other brackets */
-
- else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC)
- {
- if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
- }
-
- /* .* means "start at start or after \n" if it isn't in brackets that
- may be referenced. */
-
- else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
- {
- if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;
- }
-
- /* Check for explicit circumflex */
-
- else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
-
- /* Move on to the next alternative */
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for asserted fixed first char *
-*************************************************/
-
-/* During compilation, the "first char" settings from forward assertions are
-discarded, because they can cause conflicts with actual literals that follow.
-However, if we end up without a first char setting for an unanchored pattern,
-it is worth scanning the regex to see if there is an initial asserted first
-char. If all branches start with the same asserted char, or with a bracket all
-of whose alternatives start with the same asserted char (recurse ad lib), then
-we return that char, otherwise -1.
-
-Arguments:
- code points to start of expression (the bracket)
- inassert TRUE if in an assertion
-
-Returns: -1 or the fixed first char
-*/
-
-static int
-find_firstassertedchar(const pcre_uchar *code, BOOL inassert)
-{
-int c = -1;
-do {
- int d;
- int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
- const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl,
- TRUE);
- int op = *scode;
-
- switch(op)
- {
- default:
- return -1;
-
- case OP_BRA:
- case OP_BRAPOS:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ASSERT:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_COND:
- if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0)
- return -1;
- if (c < 0) c = d; else if (c != d) return -1;
- break;
-
- case OP_EXACT:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- if (!inassert) return -1;
- if (c < 0) c = scode[1];
- else if (c != scode[1]) return -1;
- break;
-
- case OP_EXACTI:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- if (!inassert) return -1;
- if (c < 0) c = scode[1] | REQ_CASELESS;
- else if (c != scode[1]) return -1;
- break;
- }
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT);
-return c;
-}
-
-
-
-/*************************************************
-* Compile a Regular Expression *
-*************************************************/
-
-/* This function takes a string and returns a pointer to a block of store
-holding a compiled version of the expression. The original API for this
-function had no error code return variable; it is retained for backwards
-compatibility. The new function is given a new name.
-
-Arguments:
- pattern the regular expression
- options various option bits
- errorcodeptr pointer to error code variable (pcre_compile2() only)
- can be NULL if you don't want a code value
- errorptr pointer to pointer to error text
- erroroffset ptr offset in pattern where error was detected
- tables pointer to character tables or NULL
-
-Returns: pointer to compiled data block, or NULL on error,
- with errorptr and erroroffset set
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
-pcre_compile(const char *pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-#else
-PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
-pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-#endif
-{
-#ifdef COMPILE_PCRE8
-return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-#else
-return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-#endif
-}
-
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
-pcre_compile2(const char *pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-#else
-PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
-pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-#endif
-{
-REAL_PCRE *re;
-int length = 1; /* For final END opcode */
-pcre_int32 firstchar, reqchar;
-int newline;
-int errorcode = 0;
-int skipatstart = 0;
-BOOL utf;
-size_t size;
-pcre_uchar *code;
-const pcre_uchar *codestart;
-const pcre_uchar *ptr;
-compile_data compile_block;
-compile_data *cd = &compile_block;
-
-/* This space is used for "compiling" into during the first phase, when we are
-computing the amount of memory that is needed. Compiled items are thrown away
-as soon as possible, so that a fairly large buffer should be sufficient for
-this purpose. The same space is used in the second phase for remembering where
-to fill in forward references to subpatterns. That may overflow, in which case
-new memory is obtained from malloc(). */
-
-pcre_uchar cworkspace[COMPILE_WORK_SIZE];
-
-/* Set this early so that early errors get offset 0. */
-
-ptr = (const pcre_uchar *)pattern;
-
-/* We can't pass back an error message if errorptr is NULL; I guess the best we
-can do is just return NULL, but we can set a code value if there is a code
-pointer. */
-
-if (errorptr == NULL)
- {
- if (errorcodeptr != NULL) *errorcodeptr = 99;
- return NULL;
- }
-
-*errorptr = NULL;
-if (errorcodeptr != NULL) *errorcodeptr = ERR0;
-
-/* However, we can give a message for this error */
-
-if (erroroffset == NULL)
- {
- errorcode = ERR16;
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-
-*erroroffset = 0;
-
-/* Set up pointers to the individual character tables */
-
-if (tables == NULL) tables = PRIV(default_tables);
-cd->lcc = tables + lcc_offset;
-cd->fcc = tables + fcc_offset;
-cd->cbits = tables + cbits_offset;
-cd->ctypes = tables + ctypes_offset;
-
-/* Check that all undefined public option bits are zero */
-
-if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
- {
- errorcode = ERR17;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Check for global one-time settings at the start of the pattern, and remember
-the offset for later. */
-
-while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
- ptr[skipatstart+1] == CHAR_ASTERISK)
- {
- int newnl = 0;
- int newbsr = 0;
-
-#ifdef COMPILE_PCRE8
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0)
- { skipatstart += 7; options |= PCRE_UTF8; continue; }
-#endif
-#ifdef COMPILE_PCRE16
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0)
- { skipatstart += 8; options |= PCRE_UTF16; continue; }
-#endif
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
- { skipatstart += 6; options |= PCRE_UCP; continue; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
- { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
-
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0)
- { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0)
- { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0)
- { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
-
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
-
- if (newnl != 0)
- options = (options & ~PCRE_NEWLINE_BITS) | newnl;
- else if (newbsr != 0)
- options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
- else break;
- }
-
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-utf = (options & PCRE_UTF8) != 0;
-
-/* Can't support UTF unless PCRE has been compiled to include the code. The
-return of an error code from PRIV(valid_utf)() is a new feature, introduced in
-release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is
-not used here. */
-
-#ifdef SUPPORT_UTF
-if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 &&
- (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0)
- {
-#ifdef COMPILE_PCRE8
- errorcode = ERR44;
-#else
- errorcode = ERR74;
-#endif
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-#else
-if (utf)
- {
- errorcode = ERR32;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-#endif
-
-/* Can't support UCP unless PCRE has been compiled to include the code. */
-
-#ifndef SUPPORT_UCP
-if ((options & PCRE_UCP) != 0)
- {
- errorcode = ERR67;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-#endif
-
-/* Check validity of \R options. */
-
-if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) ==
- (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- errorcode = ERR56;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Handle different types of newline. The three bits give seven cases. The
-current code allows for fixed one- or two-byte sequences, plus "any" and
-"anycrlf". */
-
-switch (options & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Build-time default */
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
- }
-
-if (newline == -2)
- {
- cd->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- cd->nltype = NLTYPE_ANY;
- }
-else
- {
- cd->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- cd->nllen = 2;
- cd->nl[0] = (newline >> 8) & 255;
- cd->nl[1] = newline & 255;
- }
- else
- {
- cd->nllen = 1;
- cd->nl[0] = newline;
- }
- }
-
-/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
-references to help in deciding whether (.*) can be treated as anchored or not.
-*/
-
-cd->top_backref = 0;
-cd->backref_map = 0;
-
-/* Reflect pattern for debugging output */
-
-DPRINTF(("------------------------------------------------------------------\n"));
-#ifdef PCRE_DEBUG
-print_puchar(stdout, (PCRE_PUCHAR)pattern);
-#endif
-DPRINTF(("\n"));
-
-/* Pretend to compile the pattern while actually just accumulating the length
-of memory required. This behaviour is triggered by passing a non-NULL final
-argument to compile_regex(). We pass a block of workspace (cworkspace) for it
-to compile parts of the pattern into; the compiled code is discarded when it is
-no longer needed, so hopefully this workspace will never overflow, though there
-is a test for its doing so. */
-
-cd->bracount = cd->final_bracount = 0;
-cd->names_found = 0;
-cd->name_entry_size = 0;
-cd->name_table = NULL;
-cd->start_code = cworkspace;
-cd->hwm = cworkspace;
-cd->start_workspace = cworkspace;
-cd->workspace_size = COMPILE_WORK_SIZE;
-cd->start_pattern = (const pcre_uchar *)pattern;
-cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
-cd->req_varyopt = 0;
-cd->assert_depth = 0;
-cd->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
-don't need to look at the result of the function here. The initial options have
-been put into the cd block so that they can be changed if an option setting is
-found within the regex right at the beginning. Bringing initial option settings
-outside can help speed up starting point checks. */
-
-ptr += skipatstart;
-code = cworkspace;
-*code = OP_BRA;
-(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
- FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length);
-if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
-
-DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
- (int)(cd->hwm - cworkspace)));
-
-if (length > MAX_PATTERN_SIZE)
- {
- errorcode = ERR20;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Compute the size of data block needed and get it, either from malloc or
-externally provided function. Integer overflow should no longer be possible
-because nowadays we limit the maximum value of cd->names_found and
-cd->name_entry_size. */
-
-size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
-re = (REAL_PCRE *)(PUBL(malloc))(size);
-
-if (re == NULL)
- {
- errorcode = ERR21;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Put in the magic number, and save the sizes, initial options, internal
-flags, and character table pointer. NULL is used for the default character
-tables. The nullpad field is at the end; it's there to help in the case when a
-regex compiled on a system with 4-byte pointers is run on another with 8-byte
-pointers. */
-
-re->magic_number = MAGIC_NUMBER;
-re->size = (int)size;
-re->options = cd->external_options;
-re->flags = cd->external_flags;
-re->first_char = 0;
-re->req_char = 0;
-re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
-re->name_entry_size = cd->name_entry_size;
-re->name_count = cd->names_found;
-re->ref_count = 0;
-re->tables = (tables == PRIV(default_tables))? NULL : tables;
-re->nullpad = NULL;
-
-/* The starting points of the name/number translation table and of the code are
-passed around in the compile data block. The start/end pattern and initial
-options are already set from the pre-compile phase, as is the name_entry_size
-field. Reset the bracket count and the names_found field. Also reset the hwm
-field; this time it's used for remembering forward references to subpatterns.
-*/
-
-cd->final_bracount = cd->bracount; /* Save for checking forward references */
-cd->assert_depth = 0;
-cd->bracount = 0;
-cd->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;
-cd->hwm = (pcre_uchar *)(cd->start_workspace);
-cd->req_varyopt = 0;
-cd->had_accept = FALSE;
-cd->check_lookbehind = FALSE;
-cd->open_caps = NULL;
-
-/* Set up a starting, non-extracting bracket, then compile the expression. On
-error, errorcode will be set non-zero, so we don't need to look at the result
-of the function here. */
-
-ptr = (const pcre_uchar *)pattern + skipatstart;
-code = (pcre_uchar *)codestart;
-*code = OP_BRA;
-(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0,
- &firstchar, &reqchar, NULL, cd, NULL);
-re->top_bracket = cd->bracount;
-re->top_backref = cd->top_backref;
-re->max_lookbehind = cd->max_lookbehind;
-re->flags = cd->external_flags | PCRE_MODE;
-
-if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */
-
-/* If not reached end of pattern on success, there's an excess bracket. */
-
-if (errorcode == 0 && *ptr != 0) errorcode = ERR22;
-
-/* Fill in the terminating state and check for disastrous overflow, but
-if debugging, leave the test till after things are printed out. */
-
-*code++ = OP_END;
-
-#ifndef PCRE_DEBUG
-if (code - codestart > length) errorcode = ERR23;
-#endif
-
-/* Fill in any forward references that are required. There may be repeated
-references; optimize for them, as searching a large regex takes time. */
-
-if (cd->hwm > cd->start_workspace)
- {
- int prev_recno = -1;
- const pcre_uchar *groupptr = NULL;
- while (errorcode == 0 && cd->hwm > cd->start_workspace)
- {
- int offset, recno;
- cd->hwm -= LINK_SIZE;
- offset = GET(cd->hwm, 0);
- recno = GET(codestart, offset);
- if (recno != prev_recno)
- {
- groupptr = PRIV(find_bracket)(codestart, utf, recno);
- prev_recno = recno;
- }
- if (groupptr == NULL) errorcode = ERR53;
- else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart));
- }
- }
-
-/* If the workspace had to be expanded, free the new memory. */
-
-if (cd->workspace_size > COMPILE_WORK_SIZE)
- (PUBL(free))((void *)cd->start_workspace);
-
-/* Give an error if there's back reference to a non-existent capturing
-subpattern. */
-
-if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
-
-/* If there were any lookbehind assertions that contained OP_RECURSE
-(recursions or subroutine calls), a flag is set for them to be checked here,
-because they may contain forward references. Actual recursions can't be fixed
-length, but subroutine calls can. It is done like this so that those without
-OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
-exceptional ones forgo this. We scan the pattern to check that they are fixed
-length, and set their lengths. */
-
-if (cd->check_lookbehind)
- {
- pcre_uchar *cc = (pcre_uchar *)codestart;
-
- /* Loop, searching for OP_REVERSE items, and process those that do not have
- their length set. (Actually, it will also re-process any that have a length
- of zero, but that is a pathological case, and it does no harm.) When we find
- one, we temporarily terminate the branch it is in while we scan it. */
-
- for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1);
- cc != NULL;
- cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1))
- {
- if (GET(cc, 1) == 0)
- {
- int fixed_length;
- pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
- int end_op = *be;
- *be = OP_END;
- fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
- cd);
- *be = end_op;
- DPRINTF(("fixed length = %d\n", fixed_length));
- if (fixed_length < 0)
- {
- errorcode = (fixed_length == -2)? ERR36 :
- (fixed_length == -4)? ERR70 : ERR25;
- break;
- }
- if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length;
- PUT(cc, 1, fixed_length);
- }
- cc += 1 + LINK_SIZE;
- }
- }
-
-/* Failed to compile, or error while post-processing */
-
-if (errorcode != 0)
- {
- (PUBL(free))(re);
- PCRE_EARLY_ERROR_RETURN:
- *erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
- PCRE_EARLY_ERROR_RETURN2:
- *errorptr = find_error_text(errorcode);
- if (errorcodeptr != NULL) *errorcodeptr = errorcode;
- return NULL;
- }
-
-/* If the anchored option was not passed, set the flag if we can determine that
-the pattern is anchored by virtue of ^ characters or \A or anything else (such
-as starting with .* when DOTALL is set).
-
-Otherwise, if we know what the first byte has to be, save it, because that
-speeds up unanchored matches no end. If not, see if we can set the
-PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
-start with ^. and also when all branches start with .* for non-DOTALL matches.
-*/
-
-if ((re->options & PCRE_ANCHORED) == 0)
- {
- if (is_anchored(codestart, 0, cd->backref_map))
- re->options |= PCRE_ANCHORED;
- else
- {
- if (firstchar < 0)
- firstchar = find_firstassertedchar(codestart, FALSE);
- if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */
- {
-#ifdef COMPILE_PCRE8
- re->first_char = firstchar & 0xff;
-#else
-#ifdef COMPILE_PCRE16
- re->first_char = firstchar & 0xffff;
-#endif
-#endif
- if ((firstchar & REQ_CASELESS) != 0)
- {
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- /* We ignore non-ASCII first chars in 8 bit mode. */
- if (utf)
- {
- if (re->first_char < 128)
- {
- if (cd->fcc[re->first_char] != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
- else if (UCD_OTHERCASE(re->first_char) != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
- else
-#endif
- if (MAX_255(re->first_char)
- && cd->fcc[re->first_char] != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
-
- re->flags |= PCRE_FIRSTSET;
- }
- else if (is_startline(codestart, 0, cd->backref_map))
- re->flags |= PCRE_STARTLINE;
- }
- }
-
-/* For an anchored pattern, we use the "required byte" only if it follows a
-variable length item in the regex. Remove the caseless flag for non-caseable
-bytes. */
-
-if (reqchar >= 0 &&
- ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0))
- {
-#ifdef COMPILE_PCRE8
- re->req_char = reqchar & 0xff;
-#else
-#ifdef COMPILE_PCRE16
- re->req_char = reqchar & 0xffff;
-#endif
-#endif
- if ((reqchar & REQ_CASELESS) != 0)
- {
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- /* We ignore non-ASCII first chars in 8 bit mode. */
- if (utf)
- {
- if (re->req_char < 128)
- {
- if (cd->fcc[re->req_char] != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
- else if (UCD_OTHERCASE(re->req_char) != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
- else
-#endif
- if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
-
- re->flags |= PCRE_REQCHSET;
- }
-
-/* Print out the compiled data if debugging is enabled. This is never the
-case when building a production library. */
-
-#ifdef PCRE_DEBUG
-printf("Length = %d top_bracket = %d top_backref = %d\n",
- length, re->top_bracket, re->top_backref);
-
-printf("Options=%08x\n", re->options);
-
-if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- pcre_uchar ch = re->first_char;
- const char *caseless =
- ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)";
- if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless);
- else printf("First char = \\x%02x%s\n", ch, caseless);
- }
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- pcre_uchar ch = re->req_char;
- const char *caseless =
- ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)";
- if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless);
- else printf("Req char = \\x%02x%s\n", ch, caseless);
- }
-
-#ifdef COMPILE_PCRE8
-pcre_printint((pcre *)re, stdout, TRUE);
-#else
-pcre16_printint((pcre *)re, stdout, TRUE);
-#endif
-
-/* This check is done here in the debugging case so that the code that
-was compiled can be seen. */
-
-if (code - codestart > length)
- {
- (PUBL(free))(re);
- *errorptr = find_error_text(ERR23);
- *erroroffset = ptr - (pcre_uchar *)pattern;
- if (errorcodeptr != NULL) *errorcodeptr = ERR23;
- return NULL;
- }
-#endif /* PCRE_DEBUG */
-
-#ifdef COMPILE_PCRE8
-return (pcre *)re;
-#else
-return (pcre16 *)re;
-#endif
-}
-
-/* End of pcre_compile.c */
diff --git a/glib/pcre/pcre_config.c b/glib/pcre/pcre_config.c
deleted file mode 100644
index 34719591f..000000000
--- a/glib/pcre/pcre_config.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_config(). */
-
-
-#include "config.h"
-
-/* Keep the original link size. */
-static int real_link_size = LINK_SIZE;
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return info about what features are configured *
-*************************************************/
-
-/* This function has an extensible interface so that additional items can be
-added compatibly.
-
-Arguments:
- what what information is required
- where where to put the information
-
-Returns: 0 if data returned, negative on error
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_config(int what, void *where)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_config(int what, void *where)
-#endif
-{
-switch (what)
- {
- case PCRE_CONFIG_UTF8:
-#if defined COMPILE_PCRE16
- *((int *)where) = 0;
- return PCRE_ERROR_BADOPTION;
-#else
-#if defined SUPPORT_UTF
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-#endif
-
- case PCRE_CONFIG_UTF16:
-#if defined COMPILE_PCRE8
- *((int *)where) = 0;
- return PCRE_ERROR_BADOPTION;
-#else
-#if defined SUPPORT_UTF
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-#endif
-
- case PCRE_CONFIG_UNICODE_PROPERTIES:
-#ifdef SUPPORT_UCP
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_JIT:
-#ifdef SUPPORT_JIT
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_JITTARGET:
-#ifdef SUPPORT_JIT
- *((const char **)where) = PRIV(jit_get_target)();
-#else
- *((const char **)where) = NULL;
-#endif
- break;
-
- case PCRE_CONFIG_NEWLINE:
- *((int *)where) = NEWLINE;
- break;
-
- case PCRE_CONFIG_BSR:
-#ifdef BSR_ANYCRLF
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_LINK_SIZE:
- *((int *)where) = real_link_size;
- break;
-
- case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
- *((int *)where) = POSIX_MALLOC_THRESHOLD;
- break;
-
- case PCRE_CONFIG_MATCH_LIMIT:
- *((unsigned long int *)where) = MATCH_LIMIT;
- break;
-
- case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
- *((unsigned long int *)where) = MATCH_LIMIT_RECURSION;
- break;
-
- case PCRE_CONFIG_STACKRECURSE:
-#ifdef NO_RECURSE
- *((int *)where) = 0;
-#else
- *((int *)where) = 1;
-#endif
- break;
-
- default: return PCRE_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-/* End of pcre_config.c */
diff --git a/glib/pcre/pcre_dfa_exec.c b/glib/pcre/pcre_dfa_exec.c
deleted file mode 100644
index 9cc82323d..000000000
--- a/glib/pcre/pcre_dfa_exec.c
+++ /dev/null
@@ -1,3611 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language (but see
-below for why this module is different).
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains the external function pcre_dfa_exec(), which is an
-alternative matching function that uses a sort of DFA algorithm (not a true
-FSM). This is NOT Perl-compatible, but it has advantages in certain
-applications. */
-
-
-/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
-the performance of his patterns greatly. I could not use it as it stood, as it
-was not thread safe, and made assumptions about pattern sizes. Also, it caused
-test 7 to loop, and test 9 to crash with a segfault.
-
-The issue is the check for duplicate states, which is done by a simple linear
-search up the state list. (Grep for "duplicate" below to find the code.) For
-many patterns, there will never be many states active at one time, so a simple
-linear search is fine. In patterns that have many active states, it might be a
-bottleneck. The suggested code used an indexing scheme to remember which states
-had previously been used for each character, and avoided the linear search when
-it knew there was no chance of a duplicate. This was implemented when adding
-states to the state lists.
-
-I wrote some thread-safe, not-limited code to try something similar at the time
-of checking for duplicates (instead of when adding states), using index vectors
-on the stack. It did give a 13% improvement with one specially constructed
-pattern for certain subject strings, but on other strings and on many of the
-simpler patterns in the test suite it did worse. The major problem, I think,
-was the extra time to initialize the index. This had to be done for each call
-of internal_dfa_exec(). (The supplied patch used a static vector, initialized
-only once - I suspect this was the cause of the problems with the tests.)
-
-Overall, I concluded that the gains in some cases did not outweigh the losses
-in others, so I abandoned this code. */
-
-
-
-#include "config.h"
-
-#define NLBLOCK md /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-
-/* For use to indent debugging output */
-
-#define SP " "
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
-into others, under special conditions. A gap of 20 between the blocks should be
-enough. The resulting opcodes don't have to be less than 256 because they are
-never stored, so we push them well clear of the normal opcodes. */
-
-#define OP_PROP_EXTRA 300
-#define OP_EXTUNI_EXTRA 320
-#define OP_ANYNL_EXTRA 340
-#define OP_HSPACE_EXTRA 360
-#define OP_VSPACE_EXTRA 380
-
-
-/* This table identifies those opcodes that are followed immediately by a
-character that is to be tested in some way. This makes it possible to
-centralize the loading of these characters. In the case of Type * etc, the
-"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
-small value. Non-zero values in the table are the offsets from the opcode where
-the character is to be found. ***NOTE*** If the start of this table is
-modified, the three tables that follow must also be modified. */
-
-static const pcre_uint8 coptable[] = {
- 0, /* End */
- 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
- 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
- 0, 0, 0, /* Any, AllAny, Anybyte */
- 0, 0, /* \P, \p */
- 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
- 0, /* \X */
- 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
- 1, /* Char */
- 1, /* Chari */
- 1, /* not */
- 1, /* noti */
- /* Positive single-char repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
- 1+IMM2_SIZE, /* exact */
- 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
- 1+IMM2_SIZE, /* exact I */
- 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
- /* Negative single-char repeats - only for chars < 256 */
- 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
- 1+IMM2_SIZE, /* NOT exact */
- 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
- 1+IMM2_SIZE, /* NOT exact I */
- 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
- /* Positive type repeats */
- 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
- 1+IMM2_SIZE, /* Type exact */
- 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
- /* Character class & ref repeats */
- 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
- 0, 0, /* CRRANGE, CRMINRANGE */
- 0, /* CLASS */
- 0, /* NCLASS */
- 0, /* XCLASS - variable length */
- 0, /* REF */
- 0, /* REFI */
- 0, /* RECURSE */
- 0, /* CALLOUT */
- 0, /* Alt */
- 0, /* Ket */
- 0, /* KetRmax */
- 0, /* KetRmin */
- 0, /* KetRpos */
- 0, /* Reverse */
- 0, /* Assert */
- 0, /* Assert not */
- 0, /* Assert behind */
- 0, /* Assert behind not */
- 0, 0, /* ONCE, ONCE_NC */
- 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
- 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
- 0, 0, /* CREF, NCREF */
- 0, 0, /* RREF, NRREF */
- 0, /* DEF */
- 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
- 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
- 0, 0 /* CLOSE, SKIPZERO */
-};
-
-/* This table identifies those opcodes that inspect a character. It is used to
-remember the fact that a character could have been inspected when the end of
-the subject is reached. ***NOTE*** If the start of this table is modified, the
-two tables that follow must also be modified. */
-
-static const pcre_uint8 poptable[] = {
- 0, /* End */
- 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
- 1, 1, 1, /* Any, AllAny, Anybyte */
- 1, 1, /* \P, \p */
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
- 1, /* \X */
- 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
- 1, /* Char */
- 1, /* Chari */
- 1, /* not */
- 1, /* noti */
- /* Positive single-char repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* upto, minupto, exact */
- 1, 1, 1, 1, /* *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
- 1, 1, 1, /* upto I, minupto I, exact I */
- 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
- /* Negative single-char repeats - only for chars < 256 */
- 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* NOT upto, minupto, exact */
- 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
- 1, 1, 1, /* NOT upto I, minupto I, exact I */
- 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
- /* Positive type repeats */
- 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* Type upto, minupto, exact */
- 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */
- /* Character class & ref repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1, 1, /* CRRANGE, CRMINRANGE */
- 1, /* CLASS */
- 1, /* NCLASS */
- 1, /* XCLASS - variable length */
- 0, /* REF */
- 0, /* REFI */
- 0, /* RECURSE */
- 0, /* CALLOUT */
- 0, /* Alt */
- 0, /* Ket */
- 0, /* KetRmax */
- 0, /* KetRmin */
- 0, /* KetRpos */
- 0, /* Reverse */
- 0, /* Assert */
- 0, /* Assert not */
- 0, /* Assert behind */
- 0, /* Assert behind not */
- 0, 0, /* ONCE, ONCE_NC */
- 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
- 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
- 0, 0, /* CREF, NCREF */
- 0, 0, /* RREF, NRREF */
- 0, /* DEF */
- 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
- 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
- 0, 0 /* CLOSE, SKIPZERO */
-};
-
-/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
-and \w */
-
-static const pcre_uint8 toptable1[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, ctype_digit,
- ctype_space, ctype_space,
- ctype_word, ctype_word,
- 0, 0 /* OP_ANY, OP_ALLANY */
-};
-
-static const pcre_uint8 toptable2[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, 0,
- ctype_space, 0,
- ctype_word, 0,
- 1, 1 /* OP_ANY, OP_ALLANY */
-};
-
-
-/* Structure for holding data about a particular state, which is in effect the
-current data for an active path through the match tree. It must consist
-entirely of ints because the working vector we are passed, and which we put
-these structures in, is a vector of ints. */
-
-typedef struct stateblock {
- int offset; /* Offset to opcode */
- int count; /* Count for repeats */
- int data; /* Some use extra data */
-} stateblock;
-
-#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int))
-
-
-#ifdef PCRE_DEBUG
-/*************************************************
-* Print character string *
-*************************************************/
-
-/* Character string printing function for debugging.
-
-Arguments:
- p points to string
- length number of bytes
- f where to print
-
-Returns: nothing
-*/
-
-static void
-pchars(const pcre_uchar *p, int length, FILE *f)
-{
-int c;
-while (length-- > 0)
- {
- if (isprint(c = *(p++)))
- fprintf(f, "%c", c);
- else
- fprintf(f, "\\x%02x", c);
- }
-}
-#endif
-
-
-
-/*************************************************
-* Execute a Regular Expression - DFA engine *
-*************************************************/
-
-/* This internal function applies a compiled pattern to a subject string,
-starting at a given point, using a DFA engine. This function is called from the
-external one, possibly multiple times if the pattern is not anchored. The
-function calls itself recursively for some kinds of subpattern.
-
-Arguments:
- md the match_data block with fixed information
- this_start_code the opening bracket of this subexpression's code
- current_subject where we currently are in the subject string
- start_offset start offset in the subject string
- offsets vector to contain the matching string offsets
- offsetcount size of same
- workspace vector of workspace
- wscount size of same
- rlevel function call recursion level
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-
-The following macros are used for adding states to the two state vectors (one
-for the current character, one for the following character). */
-
-#define ADD_ACTIVE(x,y) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state++; \
- DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_ACTIVE_DATA(x,y,z) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state->data = (z); \
- next_active_state++; \
- DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_NEW(x,y) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state++; \
- DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_NEW_DATA(x,y,z) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state->data = (z); \
- next_new_state++; \
- DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \
- (x), (y), (z), __LINE__)); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-/* And now, here is the code */
-
-static int
-internal_dfa_exec(
- dfa_match_data *md,
- const pcre_uchar *this_start_code,
- const pcre_uchar *current_subject,
- int start_offset,
- int *offsets,
- int offsetcount,
- int *workspace,
- int wscount,
- int rlevel)
-{
-stateblock *active_states, *new_states, *temp_states;
-stateblock *next_active_state, *next_new_state;
-
-const pcre_uint8 *ctypes, *lcc, *fcc;
-const pcre_uchar *ptr;
-const pcre_uchar *end_code, *first_op;
-
-dfa_recursion_info new_recursive;
-
-int active_count, new_count, match_count;
-
-/* Some fields in the md block are frequently referenced, so we load them into
-independent variables in the hope that this will perform better. */
-
-const pcre_uchar *start_subject = md->start_subject;
-const pcre_uchar *end_subject = md->end_subject;
-const pcre_uchar *start_code = md->start_code;
-
-#ifdef SUPPORT_UTF
-BOOL utf = (md->poptions & PCRE_UTF8) != 0;
-#else
-BOOL utf = FALSE;
-#endif
-
-BOOL reset_could_continue = FALSE;
-
-rlevel++;
-offsetcount &= (-2);
-
-wscount -= 2;
-wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
- (2 * INTS_PER_STATEBLOCK);
-
-DPRINTF(("\n%.*s---------------------\n"
- "%.*sCall to internal_dfa_exec f=%d\n",
- rlevel*2-2, SP, rlevel*2-2, SP, rlevel));
-
-ctypes = md->tables + ctypes_offset;
-lcc = md->tables + lcc_offset;
-fcc = md->tables + fcc_offset;
-
-match_count = PCRE_ERROR_NOMATCH; /* A negative number */
-
-active_states = (stateblock *)(workspace + 2);
-next_new_state = new_states = active_states + wscount;
-new_count = 0;
-
-first_op = this_start_code + 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
- *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
- ? IMM2_SIZE:0);
-
-/* The first thing in any (sub) pattern is a bracket of some sort. Push all
-the alternative states onto the list, and find out where the end is. This
-makes is possible to use this function recursively, when we want to stop at a
-matching internal ket rather than at the end.
-
-If the first opcode in the first alternative is OP_REVERSE, we are dealing with
-a backward assertion. In that case, we have to find out the maximum amount to
-move back, and set up each alternative appropriately. */
-
-if (*first_op == OP_REVERSE)
- {
- int max_back = 0;
- int gone_back;
-
- end_code = this_start_code;
- do
- {
- int back = GET(end_code, 2+LINK_SIZE);
- if (back > max_back) max_back = back;
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
-
- /* If we can't go back the amount required for the longest lookbehind
- pattern, go back as far as we can; some alternatives may still be viable. */
-
-#ifdef SUPPORT_UTF
- /* In character mode we have to step back character by character */
-
- if (utf)
- {
- for (gone_back = 0; gone_back < max_back; gone_back++)
- {
- if (current_subject <= start_subject) break;
- current_subject--;
- ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
- }
- }
- else
-#endif
-
- /* In byte-mode we can do this quickly. */
-
- {
- gone_back = (current_subject - max_back < start_subject)?
- (int)(current_subject - start_subject) : max_back;
- current_subject -= gone_back;
- }
-
- /* Save the earliest consulted character */
-
- if (current_subject < md->start_used_ptr)
- md->start_used_ptr = current_subject;
-
- /* Now we can process the individual branches. */
-
- end_code = this_start_code;
- do
- {
- int back = GET(end_code, 2+LINK_SIZE);
- if (back <= gone_back)
- {
- int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
- ADD_NEW_DATA(-bstate, 0, gone_back - back);
- }
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
- }
-
-/* This is the code for a "normal" subpattern (not a backward assertion). The
-start of a whole pattern is always one of these. If we are at the top level,
-we may be asked to restart matching from the same point that we reached for a
-previous partial match. We still have to scan through the top-level branches to
-find the end state. */
-
-else
- {
- end_code = this_start_code;
-
- /* Restarting */
-
- if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
- {
- do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
- new_count = workspace[1];
- if (!workspace[0])
- memcpy(new_states, active_states, new_count * sizeof(stateblock));
- }
-
- /* Not restarting */
-
- else
- {
- int length = 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
- *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
- ? IMM2_SIZE:0);
- do
- {
- ADD_NEW((int)(end_code - start_code + length), 0);
- end_code += GET(end_code, 1);
- length = 1 + LINK_SIZE;
- }
- while (*end_code == OP_ALT);
- }
- }
-
-workspace[0] = 0; /* Bit indicating which vector is current */
-
-DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code)));
-
-/* Loop for scanning the subject */
-
-ptr = current_subject;
-for (;;)
- {
- int i, j;
- int clen, dlen;
- unsigned int c, d;
- int forced_fail = 0;
- BOOL partial_newline = FALSE;
- BOOL could_continue = reset_could_continue;
- reset_could_continue = FALSE;
-
- /* Make the new state list into the active state list and empty the
- new state list. */
-
- temp_states = active_states;
- active_states = new_states;
- new_states = temp_states;
- active_count = new_count;
- new_count = 0;
-
- workspace[0] ^= 1; /* Remember for the restarting feature */
- workspace[1] = active_count;
-
-#ifdef PCRE_DEBUG
- printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
- pchars(ptr, STRLEN_UC(ptr), stdout);
- printf("\"\n");
-
- printf("%.*sActive states: ", rlevel*2-2, SP);
- for (i = 0; i < active_count; i++)
- printf("%d/%d ", active_states[i].offset, active_states[i].count);
- printf("\n");
-#endif
-
- /* Set the pointers for adding new states */
-
- next_active_state = active_states + active_count;
- next_new_state = new_states;
-
- /* Load the current character from the subject outside the loop, as many
- different states may want to look at it, and we assume that at least one
- will. */
-
- if (ptr < end_subject)
- {
- clen = 1; /* Number of data items in the character */
-#ifdef SUPPORT_UTF
- if (utf) { GETCHARLEN(c, ptr, clen); } else
-#endif /* SUPPORT_UTF */
- c = *ptr;
- }
- else
- {
- clen = 0; /* This indicates the end of the subject */
- c = NOTACHAR; /* This value should never actually be used */
- }
-
- /* Scan up the active states and act on each one. The result of an action
- may be to add more states to the currently active list (e.g. on hitting a
- parenthesis) or it may be to put states on the new list, for considering
- when we move the character pointer on. */
-
- for (i = 0; i < active_count; i++)
- {
- stateblock *current_state = active_states + i;
- BOOL caseless = FALSE;
- const pcre_uchar *code;
- int state_offset = current_state->offset;
- int count, codevalue, rrc;
-
-#ifdef PCRE_DEBUG
- printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
- if (clen == 0) printf("EOL\n");
- else if (c > 32 && c < 127) printf("'%c'\n", c);
- else printf("0x%02x\n", c);
-#endif
-
- /* A negative offset is a special case meaning "hold off going to this
- (negated) state until the number of characters in the data field have
- been skipped". If the could_continue flag was passed over from a previous
- state, arrange for it to passed on. */
-
- if (state_offset < 0)
- {
- if (current_state->data > 0)
- {
- DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
- ADD_NEW_DATA(state_offset, current_state->count,
- current_state->data - 1);
- if (could_continue) reset_could_continue = TRUE;
- continue;
- }
- else
- {
- current_state->offset = state_offset = -state_offset;
- }
- }
-
- /* Check for a duplicate state with the same count, and skip if found.
- See the note at the head of this module about the possibility of improving
- performance here. */
-
- for (j = 0; j < i; j++)
- {
- if (active_states[j].offset == state_offset &&
- active_states[j].count == current_state->count)
- {
- DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
- goto NEXT_ACTIVE_STATE;
- }
- }
-
- /* The state offset is the offset to the opcode */
-
- code = start_code + state_offset;
- codevalue = *code;
-
- /* If this opcode inspects a character, but we are at the end of the
- subject, remember the fact for use when testing for a partial match. */
-
- if (clen == 0 && poptable[codevalue] != 0)
- could_continue = TRUE;
-
- /* If this opcode is followed by an inline character, load it. It is
- tempting to test for the presence of a subject character here, but that
- is wrong, because sometimes zero repetitions of the subject are
- permitted.
-
- We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
- argument that is not a data character - but is always one byte long because
- the values are small. We have to take special action to deal with \P, \p,
- \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
- these ones to new opcodes. */
-
- if (coptable[codevalue] > 0)
- {
- dlen = 1;
-#ifdef SUPPORT_UTF
- if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
-#endif /* SUPPORT_UTF */
- d = code[coptable[codevalue]];
- if (codevalue >= OP_TYPESTAR)
- {
- switch(d)
- {
- case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
- case OP_NOTPROP:
- case OP_PROP: codevalue += OP_PROP_EXTRA; break;
- case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
- case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
- case OP_NOT_HSPACE:
- case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
- case OP_NOT_VSPACE:
- case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
- default: break;
- }
- }
- }
- else
- {
- dlen = 0; /* Not strictly necessary, but compilers moan */
- d = NOTACHAR; /* if these variables are not set. */
- }
-
-
- /* Now process the individual opcodes */
-
- switch (codevalue)
- {
-/* ========================================================================== */
- /* These cases are never obeyed. This is a fudge that causes a compile-
- time error if the vectors coptable or poptable, which are indexed by
- opcode, are not the correct length. It seems to be the only way to do
- such a check at compile time, as the sizeof() operator does not work
- in the C preprocessor. */
-
- case OP_TABLE_LENGTH:
- case OP_TABLE_LENGTH +
- ((sizeof(coptable) == OP_TABLE_LENGTH) &&
- (sizeof(poptable) == OP_TABLE_LENGTH)):
- break;
-
-/* ========================================================================== */
- /* Reached a closing bracket. If not at the end of the pattern, carry
- on with the next opcode. For repeating opcodes, also add the repeat
- state. Note that KETRPOS will always be encountered at the end of the
- subpattern, because the possessive subpattern repeats are always handled
- using recursive calls. Thus, it never adds any new states.
-
- At the end of the (sub)pattern, unless we have an empty string and
- PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
- start of the subject, save the match data, shifting up all previous
- matches so we always have the longest first. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- case OP_KETRPOS:
- if (code != end_code)
- {
- ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
- if (codevalue != OP_KET)
- {
- ADD_ACTIVE(state_offset - GET(code, 1), 0);
- }
- }
- else
- {
- if (ptr > current_subject ||
- ((md->moptions & PCRE_NOTEMPTY) == 0 &&
- ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 ||
- current_subject > start_subject + md->start_offset)))
- {
- if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
- else if (match_count > 0 && ++match_count * 2 > offsetcount)
- match_count = 0;
- count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
- if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
- if (offsetcount >= 2)
- {
- offsets[0] = (int)(current_subject - start_subject);
- offsets[1] = (int)(ptr - start_subject);
- DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
- offsets[1] - offsets[0], (char *)current_subject));
- }
- if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
- {
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
- match_count, rlevel*2-2, SP));
- return match_count;
- }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes add to the current list of states without looking
- at the current character. */
-
- /*-----------------------------------------------------------------*/
- case OP_ALT:
- do { code += GET(code, 1); } while (*code == OP_ALT);
- ADD_ACTIVE((int)(code - start_code), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRA:
- case OP_SBRA:
- do
- {
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CBRA:
- case OP_SCBRA:
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
- code += GET(code, 1);
- while (*code == OP_ALT)
- {
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- code += GET(code, 1);
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- ADD_ACTIVE(state_offset + 1, 0);
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SKIPZERO:
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CIRC:
- if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CIRCM:
- if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
- (ptr != end_subject && WAS_NEWLINE(ptr)))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EOD:
- if (ptr >= end_subject)
- {
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else { ADD_ACTIVE(state_offset + 1, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOD:
- if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOM:
- if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
-
-/* ========================================================================== */
- /* These opcodes inspect the next subject character, and sometimes
- the previous one as well, but do not have an argument. The variable
- clen contains the length of the current character and is zero if we are
- at the end of the subject. */
-
- /*-----------------------------------------------------------------*/
- case OP_ANY:
- if (clen > 0 && !IS_NEWLINE(ptr))
- {
- if (ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else
- {
- ADD_NEW(state_offset + 1, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ALLANY:
- if (clen > 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EODN:
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_DOLL:
- if ((md->moptions & PCRE_NOTEOL) == 0)
- {
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 ||
- ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
- (ptr == end_subject - md->nllen)
- ))
- { ADD_ACTIVE(state_offset + 1, 0); }
- else if (ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
- {
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else could_continue = partial_newline = TRUE;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_DOLLM:
- if ((md->moptions & PCRE_NOTEOL) == 0)
- {
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 ||
- ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
- { ADD_ACTIVE(state_offset + 1, 0); }
- else if (ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
- {
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else could_continue = partial_newline = TRUE;
- }
- }
- else if (IS_NEWLINE(ptr))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
-
- case OP_DIGIT:
- case OP_WHITESPACE:
- case OP_WORDCHAR:
- if (clen > 0 && c < 256 &&
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_NOT_WORDCHAR:
- if (clen > 0 && (c >= 256 ||
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- {
- int left_word, right_word;
-
- if (ptr > start_subject)
- {
- const pcre_uchar *temp = ptr - 1;
- if (temp < md->start_used_ptr) md->start_used_ptr = temp;
-#ifdef SUPPORT_UTF
- if (utf) { BACKCHAR(temp); }
-#endif
- GETCHARTEST(d, temp);
-#ifdef SUPPORT_UCP
- if ((md->poptions & PCRE_UCP) != 0)
- {
- if (d == '_') left_word = TRUE; else
- {
- int cat = UCD_CATEGORY(d);
- left_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
- }
- else left_word = FALSE;
-
- if (clen > 0)
- {
-#ifdef SUPPORT_UCP
- if ((md->poptions & PCRE_UCP) != 0)
- {
- if (c == '_') right_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- right_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
- }
- else right_word = FALSE;
-
- if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
- { ADD_ACTIVE(state_offset + 1, 0); }
- }
- break;
-
-
- /*-----------------------------------------------------------------*/
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs.
- */
-
-#ifdef SUPPORT_UCP
- case OP_PROP:
- case OP_NOTPROP:
- if (clen > 0)
- {
- BOOL OK;
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[1])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll ||
- chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[chartype] == code[2];
- break;
-
- case PT_PC:
- OK = chartype == code[2];
- break;
-
- case PT_SC:
- OK = UCD_SCRIPT(c) == code[2];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
- }
- break;
-#endif
-
-
-
-/* ========================================================================== */
- /* These opcodes likewise inspect the subject character, but have an
- argument that is not a data character. It is one of these opcodes:
- OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
- OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (count > 0 && codevalue == OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + 2, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are virtual opcodes that are used when something like
- OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
- argument. It keeps the code above fast for the other cases. The argument
- is in the d variable. */
-
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEPLUS:
- case OP_PROP_EXTRA + OP_TYPEMINPLUS:
- case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
- if (clen > 0)
- {
- BOOL OK;
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll ||
- chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[chartype] == code[3];
- break;
-
- case PT_PC:
- OK = chartype == code[3];
- break;
-
- case PT_SC:
- OK = UCD_SCRIPT(c) == code[3];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
- {
- const pcre_uchar *nptr = ptr + clen;
- int ncount = 0;
- if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (UCD_CATEGORY(nd) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL01;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL01:
- case 0x000a:
- if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEQUERY:
- case OP_PROP_EXTRA + OP_TYPEMINQUERY:
- case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
- count = 4;
- goto QS1;
-
- case OP_PROP_EXTRA + OP_TYPESTAR:
- case OP_PROP_EXTRA + OP_TYPEMINSTAR:
- case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS1:
-
- ADD_ACTIVE(state_offset + 4, 0);
- if (clen > 0)
- {
- BOOL OK;
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll ||
- chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[chartype] == code[3];
- break;
-
- case PT_PC:
- OK = chartype == code[3];
- break;
-
- case PT_SC:
- OK = UCD_SCRIPT(c) == code[3];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS2;
-
- case OP_EXTUNI_EXTRA + OP_TYPESTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS2:
-
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
- {
- const pcre_uchar *nptr = ptr + clen;
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (UCD_CATEGORY(nd) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS3;
-
- case OP_ANYNL_EXTRA + OP_TYPESTAR:
- case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
- case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS3:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL02;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL02:
- case 0x000a:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS4;
-
- case OP_VSPACE_EXTRA + OP_TYPESTAR:
- case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS4:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS5;
-
- case OP_HSPACE_EXTRA + OP_TYPESTAR:
- case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS5:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEEXACT:
- case OP_PROP_EXTRA + OP_TYPEUPTO:
- case OP_PROP_EXTRA + OP_TYPEMINUPTO:
- case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[1 + IMM2_SIZE + 1])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll ||
- chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[chartype] == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_PC:
- OK = chartype == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_SC:
- OK = UCD_SCRIPT(c) == code[1 + IMM2_SIZE + 2];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
- case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
- {
- const pcre_uchar *nptr = ptr + clen;
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (UCD_CATEGORY(nd) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEEXACT:
- case OP_ANYNL_EXTRA + OP_TYPEUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL03;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL03:
- case 0x000a:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEEXACT:
- case OP_VSPACE_EXTRA + OP_TYPEUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEEXACT:
- case OP_HSPACE_EXTRA + OP_TYPEUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes are followed by a character that is usually compared
- to the current subject character; it is loaded into d. We still get
- here even if there is no subject character, because in some cases zero
- repetitions are permitted. */
-
- /*-----------------------------------------------------------------*/
- case OP_CHAR:
- if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CHARI:
- if (clen == 0) break;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
- {
- unsigned int othercase;
- if (c < 128)
- othercase = fcc[c];
- else
- /* If we have Unicode property support, we can use it to test the
- other case of the character. */
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(c);
-#else
- othercase = NOTACHAR;
-#endif
-
- if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- }
- else
-#endif /* SUPPORT_UTF */
- /* Not UTF mode */
- {
- if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
- { ADD_NEW(state_offset + 2, 0); }
- }
- break;
-
-
-#ifdef SUPPORT_UCP
- /*-----------------------------------------------------------------*/
- /* This is a tricky one because it can match more than one character.
- Find out how many characters to skip, and then set up a negative state
- to wait for them to pass before continuing. */
-
- case OP_EXTUNI:
- if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
- {
- const pcre_uchar *nptr = ptr + clen;
- int ncount = 0;
- while (nptr < end_subject)
- {
- int nclen = 1;
- GETCHARLEN(c, nptr, nclen);
- if (UCD_CATEGORY(c) != ucp_M) break;
- ncount++;
- nptr += nclen;
- }
- if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- /* This is a tricky like EXTUNI because it too can match more than one
- character (when CR is followed by LF). In this case, set up a negative
- state to wait for one character to pass before continuing. */
-
- case OP_ANYNL:
- if (clen > 0) switch(c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
-
- case 0x000a:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- case 0x000d:
- if (ptr + 1 >= end_subject)
- {
- ADD_NEW(state_offset + 1, 0);
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- }
- else if (ptr[1] == 0x0a)
- {
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else
- {
- ADD_NEW(state_offset + 1, 0);
- }
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_VSPACE:
- if (clen > 0) switch(c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE:
- if (clen > 0) switch(c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- default: break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_HSPACE:
- if (clen > 0) switch(c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE:
- if (clen > 0) switch(c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- /* Match a negated single character casefully. */
-
- case OP_NOT:
- if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- /* Match a negated single character caselessly. */
-
- case OP_NOTI:
- if (clen > 0)
- {
- unsigned int otherd;
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- if (c != d && c != otherd)
- { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSPLUSI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
-
- /* Fall through */
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (count > 0 &&
- (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTPOSQUERYI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + dlen + 1, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_STARI:
- case OP_MINSTARI:
- case OP_POSSTARI:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPOSSTARI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPOSSTAR:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXACTI:
- case OP_NOTEXACTI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_EXACT:
- case OP_NOTEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_POSUPTOI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTPOSUPTOI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTPOSUPTO:
- ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UTF
- if (utf && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = UCD_OTHERCASE(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-
-/* ========================================================================== */
- /* These are the class-handling opcodes */
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
- {
- BOOL isinclass = FALSE;
- int next_state_offset;
- const pcre_uchar *ecode;
-
- /* For a simple class, there is always just a 32-byte table, and we
- can set isinclass from it. */
-
- if (codevalue != OP_XCLASS)
- {
- ecode = code + 1 + (32 / sizeof(pcre_uchar));
- if (clen > 0)
- {
- isinclass = (c > 255)? (codevalue == OP_NCLASS) :
- ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0);
- }
- }
-
- /* An extended class may have a table or a list of single characters,
- ranges, or both, and it may be positive or negative. There's a
- function that sorts all this out. */
-
- else
- {
- ecode = code + GET(code, 1);
- if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
- }
-
- /* At this point, isinclass is set for all kinds of class, and ecode
- points to the byte after the end of the class. If there is a
- quantifier, this is where it will be. */
-
- next_state_offset = (int)(ecode - start_code);
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(state_offset, 0); }
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
- if (isinclass) { count++; ADD_NEW(state_offset, count); }
- break;
-
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- count = current_state->count; /* Already matched */
- if (count >= GET2(ecode, 1))
- { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
- if (isinclass)
- {
- int max = GET2(ecode, 1 + IMM2_SIZE);
- if (++count >= max && max != 0) /* Max 0 => no limit */
- { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- break;
-
- default:
- if (isinclass) { ADD_NEW(next_state_offset, 0); }
- break;
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are the opcodes for fancy brackets of various kinds. We have
- to use recursion in order to handle them. The "always failing" assertion
- (?!) is optimised to OP_FAIL when compiling, so we have to support that,
- though the other "backtracking verbs" are not supported. */
-
- case OP_FAIL:
- forced_fail++; /* Count FAILs for multiple states */
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- {
- int rc;
- int local_offsets[2];
- int local_workspace[1000];
- const pcre_uchar *endasscode = code + GET(code, 1);
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_exec(
- md, /* static match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- (int)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- rlevel); /* function recursion level */
-
- if (rc == PCRE_ERROR_DFA_UITEM) return rc;
- if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
- { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_COND:
- case OP_SCOND:
- {
- int local_offsets[1000];
- int local_workspace[1000];
- int codelink = GET(code, 1);
- int condcode;
-
- /* Because of the way auto-callout works during compile, a callout item
- is inserted between OP_COND and an assertion condition. This does not
- happen for the other conditions. */
-
- if (code[LINK_SIZE+1] == OP_CALLOUT)
- {
- rrc = 0;
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 1; /* Version 1 of the callout block */
- cb.callout_number = code[LINK_SIZE+2];
- cb.offset_vector = offsets;
-#ifdef COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)start_subject;
-#else
- cb.subject = (PCRE_SPTR16)start_subject;
-#endif
- cb.subject_length = (int)(end_subject - start_subject);
- cb.start_match = (int)(current_subject - start_subject);
- cb.current_position = (int)(ptr - start_subject);
- cb.pattern_position = GET(code, LINK_SIZE + 3);
- cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
- cb.capture_top = 1;
- cb.capture_last = -1;
- cb.callout_data = md->callout_data;
- cb.mark = NULL; /* No (*MARK) support */
- if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
- }
- if (rrc > 0) break; /* Fail this thread */
- code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */
- }
-
- condcode = code[LINK_SIZE+1];
-
- /* Back reference conditions are not supported */
-
- if (condcode == OP_CREF || condcode == OP_NCREF)
- return PCRE_ERROR_DFA_UCOND;
-
- /* The DEFINE condition is always false */
-
- if (condcode == OP_DEF)
- { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
-
- /* The only supported version of OP_RREF is for the value RREF_ANY,
- which means "test if in any recursion". We can't test for specifically
- recursed groups. */
-
- else if (condcode == OP_RREF || condcode == OP_NRREF)
- {
- int value = GET2(code, LINK_SIZE + 2);
- if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
- if (md->recursive != NULL)
- { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
- else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
- }
-
- /* Otherwise, the condition is an assertion */
-
- else
- {
- int rc;
- const pcre_uchar *asscode = code + LINK_SIZE + 1;
- const pcre_uchar *endasscode = asscode + GET(asscode, 1);
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- asscode, /* this subexpression's code */
- ptr, /* where we currently are */
- (int)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- rlevel); /* function recursion level */
-
- if (rc == PCRE_ERROR_DFA_UITEM) return rc;
- if ((rc >= 0) ==
- (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
- { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
- else
- { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_RECURSE:
- {
- dfa_recursion_info *ri;
- int local_offsets[1000];
- int local_workspace[1000];
- const pcre_uchar *callpat = start_code + GET(code, 1);
- int recno = (callpat == md->start_code)? 0 :
- GET2(callpat, 1 + LINK_SIZE);
- int rc;
-
- DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP));
-
- /* Check for repeating a recursion without advancing the subject
- pointer. This should catch convoluted mutual recursions. (Some simple
- cases are caught at compile time.) */
-
- for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
- if (recno == ri->group_num && ptr == ri->subject_position)
- return PCRE_ERROR_RECURSELOOP;
-
- /* Remember this recursion and where we started it so as to
- catch infinite loops. */
-
- new_recursive.group_num = recno;
- new_recursive.subject_position = ptr;
- new_recursive.prevrec = md->recursive;
- md->recursive = &new_recursive;
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- callpat, /* this subexpression's code */
- ptr, /* where we currently are */
- (int)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- rlevel); /* function recursion level */
-
- md->recursive = new_recursive.prevrec; /* Done this recursion */
-
- DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP,
- rc));
-
- /* Ran out of internal offsets */
-
- if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
-
- /* For each successful matched substring, set up the next state with a
- count of characters to skip before trying it. Note that the count is in
- characters, not bytes. */
-
- if (rc > 0)
- {
- for (rc = rc*2 - 2; rc >= 0; rc -= 2)
- {
- int charcount = local_offsets[rc+1] - local_offsets[rc];
-#ifdef SUPPORT_UTF
- if (utf)
- {
- const pcre_uchar *p = start_subject + local_offsets[rc];
- const pcre_uchar *pp = start_subject + local_offsets[rc+1];
- while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
- }
-#endif
- if (charcount > 0)
- {
- ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
- }
- else
- {
- ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
- }
- }
- }
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- {
- int charcount, matched_count;
- const pcre_uchar *local_ptr = ptr;
- BOOL allow_zero;
-
- if (codevalue == OP_BRAPOSZERO)
- {
- allow_zero = TRUE;
- codevalue = *(++code); /* Codevalue will be one of above BRAs */
- }
- else allow_zero = FALSE;
-
- /* Loop to match the subpattern as many times as possible as if it were
- a complete pattern. */
-
- for (matched_count = 0;; matched_count++)
- {
- int local_offsets[2];
- int local_workspace[1000];
-
- int rc = internal_dfa_exec(
- md, /* fixed match data */
- code, /* this subexpression's code */
- local_ptr, /* where we currently are */
- (int)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- rlevel); /* function recursion level */
-
- /* Failed to match */
-
- if (rc < 0)
- {
- if (rc != PCRE_ERROR_NOMATCH) return rc;
- break;
- }
-
- /* Matched: break the loop if zero characters matched. */
-
- charcount = local_offsets[1] - local_offsets[0];
- if (charcount == 0) break;
- local_ptr += charcount; /* Advance temporary position ptr */
- }
-
- /* At this point we have matched the subpattern matched_count
- times, and local_ptr is pointing to the character after the end of the
- last match. */
-
- if (matched_count > 0 || allow_zero)
- {
- const pcre_uchar *end_subpattern = code;
- int next_state_offset;
-
- do { end_subpattern += GET(end_subpattern, 1); }
- while (*end_subpattern == OP_ALT);
- next_state_offset =
- (int)(end_subpattern - start_code + LINK_SIZE + 1);
-
- /* Optimization: if there are no more active states, and there
- are no new states yet set up, then skip over the subject string
- right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the matched substring is reached. */
-
- if (i + 1 >= active_count && new_count == 0)
- {
- ptr = local_ptr;
- clen = 0;
- ADD_NEW(next_state_offset, 0);
- }
- else
- {
- const pcre_uchar *p = ptr;
- const pcre_uchar *pp = local_ptr;
- charcount = (int)(pp - p);
-#ifdef SUPPORT_UTF
- if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
-#endif
- ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
- }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ONCE:
- case OP_ONCE_NC:
- {
- int local_offsets[2];
- int local_workspace[1000];
-
- int rc = internal_dfa_exec(
- md, /* fixed match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- (int)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- rlevel); /* function recursion level */
-
- if (rc >= 0)
- {
- const pcre_uchar *end_subpattern = code;
- int charcount = local_offsets[1] - local_offsets[0];
- int next_state_offset, repeat_state_offset;
-
- do { end_subpattern += GET(end_subpattern, 1); }
- while (*end_subpattern == OP_ALT);
- next_state_offset =
- (int)(end_subpattern - start_code + LINK_SIZE + 1);
-
- /* If the end of this subpattern is KETRMAX or KETRMIN, we must
- arrange for the repeat state also to be added to the relevant list.
- Calculate the offset, or set -1 for no repeat. */
-
- repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
- *end_subpattern == OP_KETRMIN)?
- (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
-
- /* If we have matched an empty string, add the next state at the
- current character pointer. This is important so that the duplicate
- checking kicks in, which is what breaks infinite loops that match an
- empty string. */
-
- if (charcount == 0)
- {
- ADD_ACTIVE(next_state_offset, 0);
- }
-
- /* Optimization: if there are no more active states, and there
- are no new states yet set up, then skip over the subject string
- right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the matched substring is reached. */
-
- else if (i + 1 >= active_count && new_count == 0)
- {
- ptr += charcount;
- clen = 0;
- ADD_NEW(next_state_offset, 0);
-
- /* If we are adding a repeat state at the new character position,
- we must fudge things so that it is the only current state.
- Otherwise, it might be a duplicate of one we processed before, and
- that would cause it to be skipped. */
-
- if (repeat_state_offset >= 0)
- {
- next_active_state = active_states;
- active_count = 0;
- i = -1;
- ADD_ACTIVE(repeat_state_offset, 0);
- }
- }
- else
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- const pcre_uchar *p = start_subject + local_offsets[0];
- const pcre_uchar *pp = start_subject + local_offsets[1];
- while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
- }
-#endif
- ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
- if (repeat_state_offset >= 0)
- { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
- }
- }
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
- }
- break;
-
-
-/* ========================================================================== */
- /* Handle callouts */
-
- case OP_CALLOUT:
- rrc = 0;
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 1; /* Version 1 of the callout block */
- cb.callout_number = code[1];
- cb.offset_vector = offsets;
-#ifdef COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)start_subject;
-#else
- cb.subject = (PCRE_SPTR16)start_subject;
-#endif
- cb.subject_length = (int)(end_subject - start_subject);
- cb.start_match = (int)(current_subject - start_subject);
- cb.current_position = (int)(ptr - start_subject);
- cb.pattern_position = GET(code, 2);
- cb.next_item_length = GET(code, 2 + LINK_SIZE);
- cb.capture_top = 1;
- cb.capture_last = -1;
- cb.callout_data = md->callout_data;
- cb.mark = NULL; /* No (*MARK) support */
- if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
- }
- if (rrc == 0)
- { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); }
- break;
-
-
-/* ========================================================================== */
- default: /* Unsupported opcode */
- return PCRE_ERROR_DFA_UITEM;
- }
-
- NEXT_ACTIVE_STATE: continue;
-
- } /* End of loop scanning active states */
-
- /* We have finished the processing at the current subject character. If no
- new states have been set for the next character, we have found all the
- matches that we are going to find. If we are at the top level and partial
- matching has been requested, check for appropriate conditions.
-
- The "forced_ fail" variable counts the number of (*F) encountered for the
- character. If it is equal to the original active_count (saved in
- workspace[1]) it means that (*F) was found on every active state. In this
- case we don't want to give a partial match.
-
- The "could_continue" variable is true if a state could have continued but
- for the fact that the end of the subject was reached. */
-
- if (new_count <= 0)
- {
- if (rlevel == 1 && /* Top level, and */
- could_continue && /* Some could go on, and */
- forced_fail != workspace[1] && /* Not all forced fail & */
- ( /* either... */
- (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */
- || /* or... */
- ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */
- match_count < 0) /* no matches */
- ) && /* And... */
- (
- partial_newline || /* Either partial NL */
- ( /* or ... */
- ptr >= end_subject && /* End of subject and */
- ptr > md->start_used_ptr) /* Inspected non-empty string */
- )
- )
- {
- if (offsetcount >= 2)
- {
- offsets[0] = (int)(md->start_used_ptr - start_subject);
- offsets[1] = (int)(end_subject - start_subject);
- }
- match_count = PCRE_ERROR_PARTIAL;
- }
-
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
- rlevel*2-2, SP));
- break; /* In effect, "return", but see the comment below */
- }
-
- /* One or more states are active for the next character. */
-
- ptr += clen; /* Advance to next subject character */
- } /* Loop to move along the subject string */
-
-/* Control gets here from "break" a few lines above. We do it this way because
-if we use "return" above, we have compiler trouble. Some compilers warn if
-there's nothing here because they think the function doesn't return a value. On
-the other hand, if we put a dummy statement here, some more clever compilers
-complain that it can't be reached. Sigh. */
-
-return match_count;
-}
-
-
-
-
-/*************************************************
-* Execute a Regular Expression - DFA engine *
-*************************************************/
-
-/* This external function applies a compiled re to a subject string using a DFA
-engine. This function calls the internal function multiple times if the pattern
-is not anchored.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- offsets vector of match offsets
- offsetcount size of same
- workspace workspace vector
- wscount size of same
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
- const char *subject, int length, int start_offset, int options, int *offsets,
- int offsetcount, int *workspace, int wscount)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
- PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
- int offsetcount, int *workspace, int wscount)
-#endif
-{
-REAL_PCRE *re = (REAL_PCRE *)argument_re;
-dfa_match_data match_block;
-dfa_match_data *md = &match_block;
-BOOL utf, anchored, startline, firstline;
-const pcre_uchar *current_subject, *end_subject;
-const pcre_study_data *study = NULL;
-
-const pcre_uchar *req_char_ptr;
-const pcre_uint8 *start_bits = NULL;
-BOOL has_first_char = FALSE;
-BOOL has_req_char = FALSE;
-pcre_uchar first_char = 0;
-pcre_uchar first_char2 = 0;
-pcre_uchar req_char = 0;
-pcre_uchar req_char2 = 0;
-int newline;
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || workspace == NULL ||
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
-if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
-if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
-if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-/* If restarting after a partial match, do some sanity checks on the contents
-of the workspace. */
-
-if ((options & PCRE_DFA_RESTART) != 0)
- {
- if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
- workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK)
- return PCRE_ERROR_DFA_BADRESTART;
- }
-
-/* Set up study, callout, and table data */
-
-md->tables = re->tables;
-md->callout_data = NULL;
-
-if (extra_data != NULL)
- {
- unsigned int flags = extra_data->flags;
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
- return PCRE_ERROR_DFA_UMLIMIT;
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
- md->callout_data = extra_data->callout_data;
- if ((flags & PCRE_EXTRA_TABLES) != 0)
- md->tables = extra_data->tables;
- }
-
-/* Set some local values */
-
-current_subject = (const pcre_uchar *)subject + start_offset;
-end_subject = (const pcre_uchar *)subject + length;
-req_char_ptr = current_subject - 1;
-
-#ifdef SUPPORT_UTF
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-utf = (re->options & PCRE_UTF8) != 0;
-#else
-utf = FALSE;
-#endif
-
-anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
- (re->options & PCRE_ANCHORED) != 0;
-
-/* The remaining fixed data for passing around. */
-
-md->start_code = (const pcre_uchar *)argument_re +
- re->name_table_offset + re->name_count * re->name_entry_size;
-md->start_subject = (const pcre_uchar *)subject;
-md->end_subject = end_subject;
-md->start_offset = start_offset;
-md->moptions = options;
-md->poptions = re->options;
-
-/* If the BSR option is not set at match time, copy what was set
-at compile time. */
-
-if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
- {
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
- md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
-#ifdef BSR_ANYCRLF
- else md->moptions |= PCRE_BSR_ANYCRLF;
-#endif
- }
-
-/* Handle different types of newline. The three bits give eight cases. If
-nothing is set at run time, whatever was used at compile time applies. */
-
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
- PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Compile-time default */
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-if (newline == -2)
- {
- md->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- md->nltype = NLTYPE_ANY;
- }
-else
- {
- md->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- md->nllen = 2;
- md->nl[0] = (newline >> 8) & 255;
- md->nl[1] = newline & 255;
- }
- else
- {
- md->nllen = 1;
- md->nl[0] = newline;
- }
- }
-
-/* Check a UTF-8 string if required. Unfortunately there's no way of passing
-back the character offset. */
-
-#ifdef SUPPORT_UTF
-if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- int erroroffset;
- int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset);
- if (errorcode != 0)
- {
- if (offsetcount >= 2)
- {
- offsets[0] = erroroffset;
- offsets[1] = errorcode;
- }
- return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
- }
- if (start_offset > 0 && start_offset < length &&
- NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
- return PCRE_ERROR_BADUTF8_OFFSET;
- }
-#endif
-
-/* If the exec call supplied NULL for tables, use the inbuilt ones. This
-is a feature that makes it possible to save compiled regex and re-use them
-in other programs later. */
-
-if (md->tables == NULL) md->tables = PRIV(default_tables);
-
-/* The "must be at the start of a line" flags are used in a loop when finding
-where to start. */
-
-startline = (re->flags & PCRE_STARTLINE) != 0;
-firstline = (re->options & PCRE_FIRSTLINE) != 0;
-
-/* Set up the first character to match, if available. The first_byte value is
-never set for an anchored regular expression, but the anchoring may be forced
-at run time, so we have to test for anchoring. The first char may be unset for
-an unanchored pattern, of course. If there's no first char and the pattern was
-studied, there may be a bitmap of possible first characters. */
-
-if (!anchored)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- has_first_char = TRUE;
- first_char = first_char2 = (pcre_uchar)(re->first_char);
- if ((re->flags & PCRE_FCH_CASELESS) != 0)
- {
- first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && first_char > 127)
- first_char2 = UCD_OTHERCASE(first_char);
-#endif
- }
- }
- else
- {
- if (!startline && study != NULL &&
- (study->flags & PCRE_STUDY_MAPPED) != 0)
- start_bits = study->start_bits;
- }
- }
-
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- has_req_char = TRUE;
- req_char = req_char2 = (pcre_uchar)(re->req_char);
- if ((re->flags & PCRE_RCH_CASELESS) != 0)
- {
- req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && req_char > 127)
- req_char2 = UCD_OTHERCASE(req_char);
-#endif
- }
- }
-
-/* Call the main matching function, looping for a non-anchored regex after a
-failed match. If not restarting, perform certain optimizations at the start of
-a match. */
-
-for (;;)
- {
- int rc;
-
- if ((options & PCRE_DFA_RESTART) == 0)
- {
- const pcre_uchar *save_end_subject = end_subject;
-
- /* If firstline is TRUE, the start of the match is constrained to the first
- line of a multiline string. Implement this by temporarily adjusting
- end_subject so that we stop scanning at a newline. If the match fails at
- the newline, later code breaks this loop. */
-
- if (firstline)
- {
- PCRE_PUCHAR t = current_subject;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (t < md->end_subject && !IS_NEWLINE(t))
- {
- t++;
- ACROSSCHAR(t < end_subject, *t, t++);
- }
- }
- else
-#endif
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* There are some optimizations that avoid running the match if a known
- starting point is not found. However, there is an option that disables
- these, for testing and for ensuring that all callouts do actually occur.
- The option can be set in the regex by (*NO_START_OPT) or passed in
- match-time options. */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
- {
- /* Advance to a known first char. */
-
- if (has_first_char)
- {
- if (first_char != first_char2)
- while (current_subject < end_subject &&
- *current_subject != first_char && *current_subject != first_char2)
- current_subject++;
- else
- while (current_subject < end_subject &&
- *current_subject != first_char)
- current_subject++;
- }
-
- /* Or to just after a linebreak for a multiline match if possible */
-
- else if (startline)
- {
- if (current_subject > md->start_subject + start_offset)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (current_subject < end_subject &&
- !WAS_NEWLINE(current_subject))
- {
- current_subject++;
- ACROSSCHAR(current_subject < end_subject, *current_subject,
- current_subject++);
- }
- }
- else
-#endif
- while (current_subject < end_subject && !WAS_NEWLINE(current_subject))
- current_subject++;
-
- /* If we have just passed a CR and the newline option is ANY or
- ANYCRLF, and we are now at a LF, advance the match position by one
- more character. */
-
- if (current_subject[-1] == CHAR_CR &&
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
- current_subject < end_subject &&
- *current_subject == CHAR_NL)
- current_subject++;
- }
- }
-
- /* Or to a non-unique first char after study */
-
- else if (start_bits != NULL)
- {
- while (current_subject < end_subject)
- {
- unsigned int c = *current_subject;
-#ifndef COMPILE_PCRE8
- if (c > 255) c = 255;
-#endif
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- {
- current_subject++;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- /* In non 8-bit mode, the iteration will stop for
- characters > 255 at the beginning or not stop at all. */
- if (utf)
- ACROSSCHAR(current_subject < end_subject, *current_subject,
- current_subject++);
-#endif
- }
- else break;
- }
- }
- }
-
- /* Restore fudged end_subject */
-
- end_subject = save_end_subject;
-
- /* The following two optimizations are disabled for partial matching or if
- disabling is explicitly requested (and of course, by the test above, this
- code is not obeyed when restarting after a partial match). */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 &&
- (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
- {
- /* If the pattern was studied, a minimum subject length may be set. This
- is a lower bound; no actual string of that length may actually match the
- pattern. Although the value is, strictly, in characters, we treat it as
- bytes to avoid spending too much time in this optimization. */
-
- if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
- (pcre_uint32)(end_subject - current_subject) < study->minlength)
- return PCRE_ERROR_NOMATCH;
-
- /* If req_char is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_char
- must be later in the subject; otherwise the test starts at the match
- point. This optimization can save a huge amount of work in patterns with
- nested unlimited repeats that aren't going to match. Writing separate
- code for cased/caseless versions makes it go faster, as does using an
- autoincrement and backing off on a match.
-
- HOWEVER: when the subject string is very, very long, searching to its end
- can take a long time, and give bad performance on quite ordinary
- patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
- string... so we don't do this when the string is sufficiently long. */
-
- if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX)
- {
- PCRE_PUCHAR p = current_subject + (has_first_char? 1:0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
-
- if (p > req_char_ptr)
- {
- if (req_char != req_char2)
- {
- while (p < end_subject)
- {
- int pp = *p++;
- if (pp == req_char || pp == req_char2) { p--; break; }
- }
- }
- else
- {
- while (p < end_subject)
- {
- if (*p++ == req_char) { p--; break; }
- }
- }
-
- /* If we can't find the required character, break the matching loop,
- which will cause a return or PCRE_ERROR_NOMATCH. */
-
- if (p >= end_subject) break;
-
- /* If we have found the required character, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
-
- req_char_ptr = p;
- }
- }
- }
- } /* End of optimizations that are done when not restarting */
-
- /* OK, now we can do the business */
-
- md->start_used_ptr = current_subject;
- md->recursive = NULL;
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- md->start_code, /* this subexpression's code */
- current_subject, /* where we currently are */
- start_offset, /* start offset in subject */
- offsets, /* offset vector */
- offsetcount, /* size of same */
- workspace, /* workspace vector */
- wscount, /* size of same */
- 0); /* function recurse level */
-
- /* Anything other than "no match" means we are done, always; otherwise, carry
- on only if not anchored. */
-
- if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;
-
- /* Advance to the next subject character unless we are at the end of a line
- and firstline is set. */
-
- if (firstline && IS_NEWLINE(current_subject)) break;
- current_subject++;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- ACROSSCHAR(current_subject < end_subject, *current_subject,
- current_subject++);
- }
-#endif
- if (current_subject > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. */
-
- if (current_subject[-1] == CHAR_CR &&
- current_subject < end_subject &&
- *current_subject == CHAR_NL &&
- (re->flags & PCRE_HASCRORLF) == 0 &&
- (md->nltype == NLTYPE_ANY ||
- md->nltype == NLTYPE_ANYCRLF ||
- md->nllen == 2))
- current_subject++;
-
- } /* "Bumpalong" loop */
-
-return PCRE_ERROR_NOMATCH;
-}
-
-/* End of pcre_dfa_exec.c */
diff --git a/glib/pcre/pcre_exec.c b/glib/pcre/pcre_exec.c
deleted file mode 100644
index 4ba3eda01..000000000
--- a/glib/pcre/pcre_exec.c
+++ /dev/null
@@ -1,7144 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains pcre_exec(), the externally visible function that does
-pattern matching using an NFA algorithm, trying to mimic Perl as closely as
-possible. There are also some static supporting functions. */
-
-#include "config.h"
-
-#define NLBLOCK md /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-/* Undefine some potentially clashing cpp symbols */
-
-#undef min
-#undef max
-
-/* Values for setting in md->match_function_type to indicate two special types
-of call to match(). We do it this way to save on using another stack variable,
-as stack usage is to be discouraged. */
-
-#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
-#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
-
-/* Non-error returns from the match() function. Error returns are externally
-defined PCRE_ERROR_xxx codes, which are all negative. */
-
-#define MATCH_MATCH 1
-#define MATCH_NOMATCH 0
-
-/* Special internal returns from the match() function. Make them sufficiently
-negative to avoid the external error codes. */
-
-#define MATCH_ACCEPT (-999)
-#define MATCH_COMMIT (-998)
-#define MATCH_KETRPOS (-997)
-#define MATCH_ONCE (-996)
-#define MATCH_PRUNE (-995)
-#define MATCH_SKIP (-994)
-#define MATCH_SKIP_ARG (-993)
-#define MATCH_THEN (-992)
-
-/* Maximum number of ints of offset to save on the stack for recursive calls.
-If the offset vector is bigger, malloc is used. This should be a multiple of 3,
-because the offset vector is always a multiple of 3 long. */
-
-#define REC_STACK_SAVE_MAX 30
-
-/* Min and max values for the common repeats; for the maxima, 0 => infinity */
-
-static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
-static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
-
-
-
-#ifdef PCRE_DEBUG
-/*************************************************
-* Debugging function to print chars *
-*************************************************/
-
-/* Print a sequence of chars in printable format, stopping at the end of the
-subject if the requested.
-
-Arguments:
- p points to characters
- length number to print
- is_subject TRUE if printing from within md->start_subject
- md pointer to matching data block, if is_subject is TRUE
-
-Returns: nothing
-*/
-
-static void
-pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
-{
-unsigned int c;
-if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
-while (length-- > 0)
- if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
-}
-#endif
-
-
-
-/*************************************************
-* Match a back-reference *
-*************************************************/
-
-/* Normally, if a back reference hasn't been set, the length that is passed is
-negative, so the match always fails. However, in JavaScript compatibility mode,
-the length passed is zero. Note that in caseless UTF-8 mode, the number of
-subject bytes matched may be different to the number of reference bytes.
-
-Arguments:
- offset index into the offset vector
- eptr pointer into the subject
- length length of reference to be matched (number of bytes)
- md points to match data block
- caseless TRUE if caseless
-
-Returns: >= 0 the number of subject bytes matched
- -1 no match
- -2 partial match; always given if at end subject
-*/
-
-static int
-match_ref(int offset, PCRE_PUCHAR eptr, int length, match_data *md,
- BOOL caseless)
-{
-PCRE_PUCHAR eptr_start = eptr;
-PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
-
-#ifdef PCRE_DEBUG
-if (eptr >= md->end_subject)
- printf("matching subject <null>");
-else
- {
- printf("matching subject ");
- pchars(eptr, length, TRUE, md);
- }
-printf(" against backref ");
-pchars(p, length, FALSE, md);
-printf("\n");
-#endif
-
-/* Always fail if reference not set (and not JavaScript compatible - in that
-case the length is passed as zero). */
-
-if (length < 0) return -1;
-
-/* Separate the caseless case for speed. In UTF-8 mode we can only do this
-properly if Unicode properties are supported. Otherwise, we can check only
-ASCII characters. */
-
-if (caseless)
- {
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (md->utf)
- {
- /* Match characters up to the end of the reference. NOTE: the number of
- bytes matched may differ, because there are some characters whose upper and
- lower case versions code as different numbers of bytes. For example, U+023A
- (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
- a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
- the latter. It is important, therefore, to check the length along the
- reference, not along the subject (earlier code did this wrong). */
-
- PCRE_PUCHAR endptr = p + length;
- while (p < endptr)
- {
- int c, d;
- if (eptr >= md->end_subject) return -2; /* Partial match */
- GETCHARINC(c, eptr);
- GETCHARINC(d, p);
- if (c != d && c != UCD_OTHERCASE(d)) return -1;
- }
- }
- else
-#endif
-#endif
-
- /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
- is no UCP support. */
- {
- while (length-- > 0)
- {
- if (eptr >= md->end_subject) return -2; /* Partial match */
- if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
- p++;
- eptr++;
- }
- }
- }
-
-/* In the caseful case, we can just compare the bytes, whether or not we
-are in UTF-8 mode. */
-
-else
- {
- while (length-- > 0)
- {
- if (eptr >= md->end_subject) return -2; /* Partial match */
- if (*p++ != *eptr++) return -1;
- }
- }
-
-return (int)(eptr - eptr_start);
-}
-
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-The match() function is highly recursive, though not every recursive call
-increases the recursive depth. Nevertheless, some regular expressions can cause
-it to recurse to a great depth. I was writing for Unix, so I just let it call
-itself recursively. This uses the stack for saving everything that has to be
-saved for a recursive call. On Unix, the stack can be large, and this works
-fine.
-
-It turns out that on some non-Unix-like systems there are problems with
-programs that use a lot of stack. (This despite the fact that every last chip
-has oodles of memory these days, and techniques for extending the stack have
-been known for decades.) So....
-
-There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
-calls by keeping local variables that need to be preserved in blocks of memory
-obtained from malloc() instead instead of on the stack. Macros are used to
-achieve this so that the actual code doesn't look very different to what it
-always used to.
-
-The original heap-recursive code used longjmp(). However, it seems that this
-can be very slow on some operating systems. Following a suggestion from Stan
-Switzer, the use of longjmp() has been abolished, at the cost of having to
-provide a unique number for each call to RMATCH. There is no way of generating
-a sequence of numbers at compile time in C. I have given them names, to make
-them stand out more clearly.
-
-Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
-FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
-tests. Furthermore, not using longjmp() means that local dynamic variables
-don't have indeterminate values; this has meant that the frame size can be
-reduced because the result can be "passed back" by straight setting of the
-variable instead of being passed in the frame.
-****************************************************************************
-***************************************************************************/
-
-/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
-below must be updated in sync. */
-
-enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
- RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
- RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
- RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
- RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
- RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
- RM61, RM62, RM63, RM64, RM65, RM66 };
-
-/* These versions of the macros use the stack, as normal. There are debugging
-versions and production versions. Note that the "rw" argument of RMATCH isn't
-actually used in this definition. */
-
-#ifndef NO_RECURSE
-
-#ifdef PCRE_DEBUG
-#define RMATCH(ra,rb,rc,rd,re,rw) \
- { \
- printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
- printf("to line %d\n", __LINE__); \
- }
-#define RRETURN(ra) \
- { \
- printf("match() returned %d from line %d ", ra, __LINE__); \
- return ra; \
- }
-#else
-#define RMATCH(ra,rb,rc,rd,re,rw) \
- rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
-#define RRETURN(ra) return ra
-#endif
-
-#else
-
-
-/* These versions of the macros manage a private stack on the heap. Note that
-the "rd" argument of RMATCH isn't actually used in this definition. It's the md
-argument of match(), which never changes. */
-
-#define RMATCH(ra,rb,rc,rd,re,rw)\
- {\
- heapframe *newframe = frame->Xnextframe;\
- if (newframe == NULL)\
- {\
- newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
- if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
- newframe->Xnextframe = NULL;\
- frame->Xnextframe = newframe;\
- }\
- frame->Xwhere = rw;\
- newframe->Xeptr = ra;\
- newframe->Xecode = rb;\
- newframe->Xmstart = mstart;\
- newframe->Xoffset_top = rc;\
- newframe->Xeptrb = re;\
- newframe->Xrdepth = frame->Xrdepth + 1;\
- newframe->Xprevframe = frame;\
- frame = newframe;\
- DPRINTF(("restarting from line %d\n", __LINE__));\
- goto HEAP_RECURSE;\
- L_##rw:\
- DPRINTF(("jumped back to line %d\n", __LINE__));\
- }
-
-#define RRETURN(ra)\
- {\
- heapframe *oldframe = frame;\
- frame = oldframe->Xprevframe;\
- if (frame != NULL)\
- {\
- rrc = ra;\
- goto HEAP_RETURN;\
- }\
- return ra;\
- }
-
-
-/* Structure for remembering the local variables in a private frame */
-
-typedef struct heapframe {
- struct heapframe *Xprevframe;
- struct heapframe *Xnextframe;
-
- /* Function arguments that may change */
-
- PCRE_PUCHAR Xeptr;
- const pcre_uchar *Xecode;
- PCRE_PUCHAR Xmstart;
- int Xoffset_top;
- eptrblock *Xeptrb;
- unsigned int Xrdepth;
-
- /* Function local variables */
-
- PCRE_PUCHAR Xcallpat;
-#ifdef SUPPORT_UTF
- PCRE_PUCHAR Xcharptr;
-#endif
- PCRE_PUCHAR Xdata;
- PCRE_PUCHAR Xnext;
- PCRE_PUCHAR Xpp;
- PCRE_PUCHAR Xprev;
- PCRE_PUCHAR Xsaved_eptr;
-
- recursion_info Xnew_recursive;
-
- BOOL Xcur_is_word;
- BOOL Xcondition;
- BOOL Xprev_is_word;
-
-#ifdef SUPPORT_UCP
- int Xprop_type;
- int Xprop_value;
- int Xprop_fail_result;
- int Xoclength;
- pcre_uchar Xocchars[6];
-#endif
-
- int Xcodelink;
- int Xctype;
- unsigned int Xfc;
- int Xfi;
- int Xlength;
- int Xmax;
- int Xmin;
- int Xnumber;
- int Xoffset;
- int Xop;
- int Xsave_capture_last;
- int Xsave_offset1, Xsave_offset2, Xsave_offset3;
- int Xstacksave[REC_STACK_SAVE_MAX];
-
- eptrblock Xnewptrb;
-
- /* Where to jump back to */
-
- int Xwhere;
-
-} heapframe;
-
-#endif
-
-
-/***************************************************************************
-***************************************************************************/
-
-
-
-/*************************************************
-* Match from current position *
-*************************************************/
-
-/* This function is called recursively in many circumstances. Whenever it
-returns a negative (error) response, the outer incarnation must also return the
-same response. */
-
-/* These macros pack up tests that are used for partial matching, and which
-appear several times in the code. We set the "hit end" flag if the pointer is
-at the end of the subject and also past the start of the subject (i.e.
-something has been matched). For hard partial matching, we then return
-immediately. The second one is used when we already know we are past the end of
-the subject. */
-
-#define CHECK_PARTIAL()\
- if (md->partial != 0 && eptr >= md->end_subject && \
- eptr > md->start_used_ptr) \
- { \
- md->hitend = TRUE; \
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
- }
-
-#define SCHECK_PARTIAL()\
- if (md->partial != 0 && eptr > md->start_used_ptr) \
- { \
- md->hitend = TRUE; \
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
- }
-
-
-/* Performance note: It might be tempting to extract commonly used fields from
-the md structure (e.g. utf, end_subject) into individual variables to improve
-performance. Tests using gcc on a SPARC disproved this; in the first case, it
-made performance worse.
-
-Arguments:
- eptr pointer to current character in subject
- ecode pointer to current position in compiled code
- mstart pointer to the current match start position (can be modified
- by encountering \K)
- offset_top current top pointer
- md pointer to "static" info for the match
- eptrb pointer to chain of blocks containing eptr at start of
- brackets - for testing for empty matches
- rdepth the recursion depth
-
-Returns: MATCH_MATCH if matched ) these values are >= 0
- MATCH_NOMATCH if failed to match )
- a negative MATCH_xxx value for PRUNE, SKIP, etc
- a negative PCRE_ERROR_xxx value if aborted by an error condition
- (e.g. stopped by repeated call or recursion limit)
-*/
-
-static int
-match(PCRE_PUCHAR eptr, const pcre_uchar *ecode,
- PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
- unsigned int rdepth)
-{
-/* These variables do not need to be preserved over recursion in this function,
-so they can be ordinary variables in all cases. Mark some of them with
-"register" because they are used a lot in loops. */
-
-int rrc; /* Returns from recursive calls */
-int i; /* Used for loops not involving calls to RMATCH() */
-unsigned int c; /* Character values not kept over RMATCH() calls */
-BOOL utf; /* Local copy of UTF flag for speed */
-
-BOOL minimize, possessive; /* Quantifier options */
-BOOL caseless;
-int condcode;
-
-/* When recursion is not being used, all "local" variables that have to be
-preserved over calls to RMATCH() are part of a "frame". We set up the top-level
-frame on the stack here; subsequent instantiations are obtained from the heap
-whenever RMATCH() does a "recursion". See the macro definitions above. Putting
-the top-level on the stack rather than malloc-ing them all gives a performance
-boost in many cases where there is not much "recursion". */
-
-#ifdef NO_RECURSE
-heapframe *frame = (heapframe *)md->match_frames_base;
-
-/* Copy in the original argument variables */
-
-frame->Xeptr = eptr;
-frame->Xecode = ecode;
-frame->Xmstart = mstart;
-frame->Xoffset_top = offset_top;
-frame->Xeptrb = eptrb;
-frame->Xrdepth = rdepth;
-
-/* This is where control jumps back to to effect "recursion" */
-
-HEAP_RECURSE:
-
-/* Macros make the argument variables come from the current frame */
-
-#define eptr frame->Xeptr
-#define ecode frame->Xecode
-#define mstart frame->Xmstart
-#define offset_top frame->Xoffset_top
-#define eptrb frame->Xeptrb
-#define rdepth frame->Xrdepth
-
-/* Ditto for the local variables */
-
-#ifdef SUPPORT_UTF
-#define charptr frame->Xcharptr
-#endif
-#define callpat frame->Xcallpat
-#define codelink frame->Xcodelink
-#define data frame->Xdata
-#define next frame->Xnext
-#define pp frame->Xpp
-#define prev frame->Xprev
-#define saved_eptr frame->Xsaved_eptr
-
-#define new_recursive frame->Xnew_recursive
-
-#define cur_is_word frame->Xcur_is_word
-#define condition frame->Xcondition
-#define prev_is_word frame->Xprev_is_word
-
-#ifdef SUPPORT_UCP
-#define prop_type frame->Xprop_type
-#define prop_value frame->Xprop_value
-#define prop_fail_result frame->Xprop_fail_result
-#define oclength frame->Xoclength
-#define occhars frame->Xocchars
-#endif
-
-#define ctype frame->Xctype
-#define fc frame->Xfc
-#define fi frame->Xfi
-#define length frame->Xlength
-#define max frame->Xmax
-#define min frame->Xmin
-#define number frame->Xnumber
-#define offset frame->Xoffset
-#define op frame->Xop
-#define save_capture_last frame->Xsave_capture_last
-#define save_offset1 frame->Xsave_offset1
-#define save_offset2 frame->Xsave_offset2
-#define save_offset3 frame->Xsave_offset3
-#define stacksave frame->Xstacksave
-
-#define newptrb frame->Xnewptrb
-
-/* When recursion is being used, local variables are allocated on the stack and
-get preserved during recursion in the normal way. In this environment, fi and
-i, and fc and c, can be the same variables. */
-
-#else /* NO_RECURSE not defined */
-#define fi i
-#define fc c
-
-/* Many of the following variables are used only in small blocks of the code.
-My normal style of coding would have declared them within each of those blocks.
-However, in order to accommodate the version of this code that uses an external
-"stack" implemented on the heap, it is easier to declare them all here, so the
-declarations can be cut out in a block. The only declarations within blocks
-below are for variables that do not have to be preserved over a recursive call
-to RMATCH(). */
-
-#ifdef SUPPORT_UTF
-const pcre_uchar *charptr;
-#endif
-const pcre_uchar *callpat;
-const pcre_uchar *data;
-const pcre_uchar *next;
-PCRE_PUCHAR pp;
-const pcre_uchar *prev;
-PCRE_PUCHAR saved_eptr;
-
-recursion_info new_recursive;
-
-BOOL cur_is_word;
-BOOL condition;
-BOOL prev_is_word;
-
-#ifdef SUPPORT_UCP
-int prop_type;
-int prop_value;
-int prop_fail_result;
-int oclength;
-pcre_uchar occhars[6];
-#endif
-
-int codelink;
-int ctype;
-int length;
-int max;
-int min;
-int number;
-int offset;
-int op;
-int save_capture_last;
-int save_offset1, save_offset2, save_offset3;
-int stacksave[REC_STACK_SAVE_MAX];
-
-eptrblock newptrb;
-
-/* There is a special fudge for calling match() in a way that causes it to
-measure the size of its basic stack frame when the stack is being used for
-recursion. The second argument (ecode) being NULL triggers this behaviour. It
-cannot normally ever be NULL. The return is the negated value of the frame
-size. */
-
-if (ecode == NULL)
- {
- if (rdepth == 0)
- return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
- else
- {
- int len = (char *)&rdepth - (char *)eptr;
- return (len > 0)? -len : len;
- }
- }
-#endif /* NO_RECURSE */
-
-/* To save space on the stack and in the heap frame, I have doubled up on some
-of the local variables that are used only in localised parts of the code, but
-still need to be preserved over recursive calls of match(). These macros define
-the alternative names that are used. */
-
-#define allow_zero cur_is_word
-#define cbegroup condition
-#define code_offset codelink
-#define condassert condition
-#define matched_once prev_is_word
-#define foc number
-#define save_mark data
-
-/* These statements are here to stop the compiler complaining about unitialized
-variables. */
-
-#ifdef SUPPORT_UCP
-prop_value = 0;
-prop_fail_result = 0;
-#endif
-
-
-/* This label is used for tail recursion, which is used in a few cases even
-when NO_RECURSE is not defined, in order to reduce the amount of stack that is
-used. Thanks to Ian Taylor for noticing this possibility and sending the
-original patch. */
-
-TAIL_RECURSE:
-
-/* OK, now we can get on with the real code of the function. Recursive calls
-are specified by the macro RMATCH and RRETURN is used to return. When
-NO_RECURSE is *not* defined, these just turn into a recursive call to match()
-and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
-defined). However, RMATCH isn't like a function call because it's quite a
-complicated macro. It has to be used in one particular way. This shouldn't,
-however, impact performance when true recursion is being used. */
-
-#ifdef SUPPORT_UTF
-utf = md->utf; /* Local copy of the flag */
-#else
-utf = FALSE;
-#endif
-
-/* First check that we haven't called match() too many times, or that we
-haven't exceeded the recursive call limit. */
-
-if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
-if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
-
-/* At the start of a group with an unlimited repeat that may match an empty
-string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is
-done this way to save having to use another function argument, which would take
-up space on the stack. See also MATCH_CONDASSERT below.
-
-When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
-such remembered pointers, to be checked when we hit the closing ket, in order
-to break infinite loops that match no characters. When match() is called in
-other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
-NOT be used with tail recursion, because the memory block that is used is on
-the stack, so a new one may be required for each match(). */
-
-if (md->match_function_type == MATCH_CBEGROUP)
- {
- newptrb.epb_saved_eptr = eptr;
- newptrb.epb_prev = eptrb;
- eptrb = &newptrb;
- md->match_function_type = 0;
- }
-
-/* Now start processing the opcodes. */
-
-for (;;)
- {
- minimize = possessive = FALSE;
- op = *ecode;
-
- switch(op)
- {
- case OP_MARK:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM55);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
-
- /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
- argument, and we must check whether that argument matches this MARK's
- argument. It is passed back in md->start_match_ptr (an overloading of that
- variable). If it does match, we reset that variable to the current subject
- position and return MATCH_SKIP. Otherwise, pass back the return code
- unaltered. */
-
- else if (rrc == MATCH_SKIP_ARG &&
- STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
- {
- md->start_match_ptr = eptr;
- RRETURN(MATCH_SKIP);
- }
- RRETURN(rrc);
-
- case OP_FAIL:
- RRETURN(MATCH_NOMATCH);
-
- /* COMMIT overrides PRUNE, SKIP, and THEN */
-
- case OP_COMMIT:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM52);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
- rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
- rrc != MATCH_THEN)
- RRETURN(rrc);
- RRETURN(MATCH_COMMIT);
-
- /* PRUNE overrides THEN */
-
- case OP_PRUNE:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM51);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- RRETURN(MATCH_PRUNE);
-
- case OP_PRUNE_ARG:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM56);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- RRETURN(MATCH_PRUNE);
-
- /* SKIP overrides PRUNE and THEN */
-
- case OP_SKIP:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM53);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
- RRETURN(rrc);
- md->start_match_ptr = eptr; /* Pass back current position */
- RRETURN(MATCH_SKIP);
-
- /* Note that, for Perl compatibility, SKIP with an argument does NOT set
- nomatch_mark. There is a flag that disables this opcode when re-matching a
- pattern that ended with a SKIP for which there was not a matching MARK. */
-
- case OP_SKIP_ARG:
- if (md->ignore_skip_arg)
- {
- ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
- break;
- }
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM57);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
- RRETURN(rrc);
-
- /* Pass back the current skip name by overloading md->start_match_ptr and
- returning the special MATCH_SKIP_ARG return code. This will either be
- caught by a matching MARK, or get to the top, where it causes a rematch
- with the md->ignore_skip_arg flag set. */
-
- md->start_match_ptr = ecode + 2;
- RRETURN(MATCH_SKIP_ARG);
-
- /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
- the branch in which it occurs can be determined. Overload the start of
- match pointer to do this. */
-
- case OP_THEN:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM54);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode;
- RRETURN(MATCH_THEN);
-
- case OP_THEN_ARG:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
- md, eptrb, RM58);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode;
- RRETURN(MATCH_THEN);
-
- /* Handle an atomic group that does not contain any capturing parentheses.
- This can be handled like an assertion. Prior to 8.13, all atomic groups
- were handled this way. In 8.13, the code was changed as below for ONCE, so
- that backups pass through the group and thereby reset captured values.
- However, this uses a lot more stack, so in 8.20, atomic groups that do not
- contain any captures generate OP_ONCE_NC, which can be handled in the old,
- less stack intensive way.
-
- Check the alternative branches in turn - the matching won't pass the KET
- for this kind of subpattern. If any one branch matches, we carry on as at
- the end of a normal bracket, leaving the subject pointer, but resetting
- the start-of-match value in case it was changed by \K. */
-
- case OP_ONCE_NC:
- prev = ecode;
- saved_eptr = eptr;
- save_mark = md->mark;
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
- if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
- {
- mstart = md->start_match_ptr;
- break;
- }
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += GET(ecode,1);
- md->mark = save_mark;
- }
- while (*ecode == OP_ALT);
-
- /* If hit the end of the group (which could be repeated), fail */
-
- if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
-
- /* Continue as from after the group, updating the offsets high water
- mark, since extracts may have been taken. */
-
- do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- ecode += 1+LINK_SIZE;
- break;
- }
-
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. The second "call" of match()
- uses tail recursion, to avoid using another stack frame. */
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode = prev;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* Handle a capturing bracket, other than those that are possessive with an
- unlimited repeat. If there is space in the offset vector, save the current
- subject position in the working slot at the top of the vector. We mustn't
- change the current values of the data slot, because they may be set from a
- previous iteration of this group, and be referred to by a reference inside
- the group. A failure to match might occur after the group has succeeded,
- if something later on doesn't match. For this reason, we need to restore
- the working value and also the values of the final offsets, in case they
- were set by a previous iteration of the same bracket.
-
- If there isn't enough space in the offset vector, treat this as if it were
- a non-capturing bracket. Don't worry about setting the flag for the error
- case here; that is handled in the code for KET. */
-
- case OP_CBRA:
- case OP_SCBRA:
- number = GET2(ecode, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("start bracket %d\n", number);
- printf("subject=");
- pchars(eptr, 16, TRUE, md);
- printf("\n");
-#endif
-
- if (offset < md->offset_max)
- {
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
- save_mark = md->mark;
-
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
- md->offset_vector[md->offset_end - number] =
- (int)(eptr - md->start_subject);
-
- for (;;)
- {
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM1);
- if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
-
- /* If we backed up to a THEN, check whether it is within the current
- branch by comparing the address of the THEN that is passed back with
- the end of the branch. If it is within the current branch, and the
- branch is one of two or more alternatives (it either starts or ends
- with OP_ALT), we have reached the limit of THEN's action, so convert
- the return code to NOMATCH, which will cause normal backtracking to
- happen from now on. Otherwise, THEN is passed back to an outer
- alternative. This implements Perl's treatment of parenthesized groups,
- where a group not containing | does not affect the current alternative,
- that is, (X) is NOT the same as (X|(*F)). */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- /* Anything other than NOMATCH is passed back. */
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- md->mark = save_mark;
- if (*ecode != OP_ALT) break;
- }
-
- DPRINTF(("bracket %d failed\n", number));
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
-
- /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
-
- RRETURN(rrc);
- }
-
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- /* Non-capturing or atomic group, except for possessive with unlimited
- repeat and ONCE group with no captures. Loop for all the alternatives.
-
- When we get to the final alternative within the brackets, we used to return
- the result of a recursive call to match() whatever happened so it was
- possible to reduce stack usage by turning this into a tail recursion,
- except in the case of a possibly empty group. However, now that there is
- the possiblity of (*THEN) occurring in the final alternative, this
- optimization is no longer always possible.
-
- We can optimize if we know there are no (*THEN)s in the pattern; at present
- this is the best that can be done.
-
- MATCH_ONCE is returned when the end of an atomic group is successfully
- reached, but subsequent matching fails. It passes back up the tree (causing
- captured values to be reset) until the original atomic group level is
- reached. This is tested by comparing md->once_target with the start of the
- group. At this point, the return is converted into MATCH_NOMATCH so that
- previous backup points can be taken. */
-
- case OP_ONCE:
- case OP_BRA:
- case OP_SBRA:
- DPRINTF(("start non-capturing bracket\n"));
-
- for (;;)
- {
- if (op >= OP_SBRA || op == OP_ONCE)
- md->match_function_type = MATCH_CBEGROUP;
-
- /* If this is not a possibly empty group, and there are no (*THEN)s in
- the pattern, and this is the final alternative, optimize as described
- above. */
-
- else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
- {
- ecode += PRIV(OP_lengths)[*ecode];
- goto TAIL_RECURSE;
- }
-
- /* In all other cases, we have to make another call to match(). */
-
- save_mark = md->mark;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
- RM2);
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH)
- {
- if (rrc == MATCH_ONCE)
- {
- const pcre_uchar *scode = ecode;
- if (*scode != OP_ONCE) /* If not at start, find it */
- {
- while (*scode == OP_ALT) scode += GET(scode, 1);
- scode -= GET(scode, 1);
- }
- if (md->once_target == scode) rrc = MATCH_NOMATCH;
- }
- RRETURN(rrc);
- }
- ecode += GET(ecode, 1);
- md->mark = save_mark;
- if (*ecode != OP_ALT) break;
- }
-
- RRETURN(MATCH_NOMATCH);
-
- /* Handle possessive capturing brackets with an unlimited repeat. We come
- here from BRAZERO with allow_zero set TRUE. The offset_vector values are
- handled similarly to the normal case above. However, the matching is
- different. The end of these brackets will always be OP_KETRPOS, which
- returns MATCH_KETRPOS without going further in the pattern. By this means
- we can handle the group by iteration rather than recursion, thereby
- reducing the amount of stack needed. */
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- allow_zero = FALSE;
-
- POSSESSIVE_CAPTURE:
- number = GET2(ecode, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("start possessive bracket %d\n", number);
- printf("subject=");
- pchars(eptr, 16, TRUE, md);
- printf("\n");
-#endif
-
- if (offset < md->offset_max)
- {
- matched_once = FALSE;
- code_offset = (int)(ecode - md->start_code);
-
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
-
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
-
- /* Each time round the loop, save the current subject position for use
- when the group matches. For MATCH_MATCH, the group has matched, so we
- restart it with a new subject starting position, remembering that we had
- at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
- usual. If we haven't matched any alternatives in any iteration, check to
- see if a previous iteration matched. If so, the group has matched;
- continue from afterwards. Otherwise it has failed; restore the previous
- capture values before returning NOMATCH. */
-
- for (;;)
- {
- md->offset_vector[md->offset_end - number] =
- (int)(eptr - md->start_subject);
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM63);
- if (rrc == MATCH_KETRPOS)
- {
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
- ecode = md->start_code + code_offset;
- save_capture_last = md->capture_last;
- matched_once = TRUE;
- continue;
- }
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- if (*ecode != OP_ALT) break;
- }
-
- if (!matched_once)
- {
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
- }
-
- if (allow_zero || matched_once)
- {
- ecode += 1 + LINK_SIZE;
- break;
- }
-
- RRETURN(MATCH_NOMATCH);
- }
-
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- /* Non-capturing possessive bracket with unlimited repeat. We come here
- from BRAZERO with allow_zero = TRUE. The code is similar to the above,
- without the capturing complication. It is written out separately for speed
- and cleanliness. */
-
- case OP_BRAPOS:
- case OP_SBRAPOS:
- allow_zero = FALSE;
-
- POSSESSIVE_NON_CAPTURE:
- matched_once = FALSE;
- code_offset = (int)(ecode - md->start_code);
-
- for (;;)
- {
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM48);
- if (rrc == MATCH_KETRPOS)
- {
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
- ecode = md->start_code + code_offset;
- matched_once = TRUE;
- continue;
- }
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += GET(ecode, 1);
- if (*ecode != OP_ALT) break;
- }
-
- if (matched_once || allow_zero)
- {
- ecode += 1 + LINK_SIZE;
- break;
- }
- RRETURN(MATCH_NOMATCH);
-
- /* Control never reaches here. */
-
- /* Conditional group: compilation checked that there are no more than
- two branches. If the condition is false, skipping the first branch takes us
- past the end if there is only one branch, but that's OK because that is
- exactly what going to the ket would do. */
-
- case OP_COND:
- case OP_SCOND:
- codelink = GET(ecode, 1);
-
- /* Because of the way auto-callout works during compile, a callout item is
- inserted between OP_COND and an assertion condition. */
-
- if (ecode[LINK_SIZE+1] == OP_CALLOUT)
- {
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 2; /* Version 1 of the callout block */
- cb.callout_number = ecode[LINK_SIZE+2];
- cb.offset_vector = md->offset_vector;
-#ifdef COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)md->start_subject;
-#else
- cb.subject = (PCRE_SPTR16)md->start_subject;
-#endif
- cb.subject_length = (int)(md->end_subject - md->start_subject);
- cb.start_match = (int)(mstart - md->start_subject);
- cb.current_position = (int)(eptr - md->start_subject);
- cb.pattern_position = GET(ecode, LINK_SIZE + 3);
- cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
- cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last;
- cb.callout_data = md->callout_data;
- cb.mark = md->nomatch_mark;
- if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- }
- ecode += PRIV(OP_lengths)[OP_CALLOUT];
- }
-
- condcode = ecode[LINK_SIZE+1];
-
- /* Now see what the actual condition is */
-
- if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
- {
- if (md->recursive == NULL) /* Not recursing => FALSE */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
- else
- {
- int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
- condition = (recno == RREF_ANY || recno == md->recursive->group_num);
-
- /* If the test is for recursion into a specific subpattern, and it is
- false, but the test was set up by name, scan the table to see if the
- name refers to any other numbers, and test them. The condition is true
- if any one is set. */
-
- if (!condition && condcode == OP_NRREF)
- {
- pcre_uchar *slotA = md->name_table;
- for (i = 0; i < md->name_count; i++)
- {
- if (GET2(slotA, 0) == recno) break;
- slotA += md->name_entry_size;
- }
-
- /* Found a name for the number - there can be only one; duplicate
- names for different numbers are allowed, but not vice versa. First
- scan down for duplicates. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
- }
- }
- }
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
- }
- }
-
- else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
- {
- offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
- condition = offset < offset_top && md->offset_vector[offset] >= 0;
-
- /* If the numbered capture is unset, but the reference was by name,
- scan the table to see if the name refers to any other numbers, and test
- them. The condition is true if any one is set. This is tediously similar
- to the code above, but not close enough to try to amalgamate. */
-
- if (!condition && condcode == OP_NCREF)
- {
- int refno = offset >> 1;
- pcre_uchar *slotA = md->name_table;
-
- for (i = 0; i < md->name_count; i++)
- {
- if (GET2(slotA, 0) == refno) break;
- slotA += md->name_entry_size;
- }
-
- /* Found a name for the number - there can be only one; duplicate names
- for different numbers are allowed, but not vice versa. First scan down
- for duplicates. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
- }
- }
- }
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
- }
-
- else if (condcode == OP_DEF) /* DEFINE - always false */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
-
- /* The condition is an assertion. Call match() to evaluate it - setting
- md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
- an assertion. */
-
- else
- {
- md->match_function_type = MATCH_CONDASSERT;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
- if (rrc == MATCH_MATCH)
- {
- if (md->end_offset_top > offset_top)
- offset_top = md->end_offset_top; /* Captures may have happened */
- condition = TRUE;
- ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
- while (*ecode == OP_ALT) ecode += GET(ecode, 1);
- }
-
- /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
- assertion; it is therefore treated as NOMATCH. */
-
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
- {
- RRETURN(rrc); /* Need braces because of following else */
- }
- else
- {
- condition = FALSE;
- ecode += codelink;
- }
- }
-
- /* We are now at the branch that is to be obeyed. As there is only one, can
- use tail recursion to avoid using another stack frame, except when there is
- unlimited repeat of a possibly empty group. In the latter case, a recursive
- call to match() is always required, unless the second alternative doesn't
- exist, in which case we can just plough on. Note that, for compatibility
- with Perl, the | in a conditional group is NOT treated as creating two
- alternatives. If a THEN is encountered in the branch, it propagates out to
- the enclosing alternative (unless nested in a deeper set of alternatives,
- of course). */
-
- if (condition || *ecode == OP_ALT)
- {
- if (op != OP_SCOND)
- {
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
-
- md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
- RRETURN(rrc);
- }
-
- /* Condition false & no alternative; continue after the group. */
-
- else
- {
- ecode += 1 + LINK_SIZE;
- }
- break;
-
-
- /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
- to close any currently open capturing brackets. */
-
- case OP_CLOSE:
- number = GET2(ecode, 1);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("end bracket %d at *ACCEPT", number);
- printf("\n");
-#endif
-
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
- {
- md->offset_vector[offset] =
- md->offset_vector[md->offset_end - number];
- md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
- if (offset_top <= offset) offset_top = offset + 2;
- }
- ecode += 1 + IMM2_SIZE;
- break;
-
-
- /* End of the pattern, either real or forced. */
-
- case OP_END:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
-
- /* If we have matched an empty string, fail if not in an assertion and not
- in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART
- is set and we have matched at the start of the subject. In both cases,
- backtracking will then try other alternatives, if any. */
-
- if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
- md->recursive == NULL &&
- (md->notempty ||
- (md->notempty_atstart &&
- mstart == md->start_subject + md->start_offset)))
- RRETURN(MATCH_NOMATCH);
-
- /* Otherwise, we have a match. */
-
- md->end_match_ptr = eptr; /* Record where we ended */
- md->end_offset_top = offset_top; /* and how many extracts were taken */
- md->start_match_ptr = mstart; /* and the start (\K can modify) */
-
- /* For some reason, the macros don't work properly if an expression is
- given as the argument to RRETURN when the heap is in use. */
-
- rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
- RRETURN(rrc);
-
- /* Assertion brackets. Check the alternative branches in turn - the
- matching won't pass the KET for an assertion. If any one branch matches,
- the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
- start of each branch to move the current point backwards, so the code at
- this level is identical to the lookahead case. When the assertion is part
- of a condition, we want to return immediately afterwards. The caller of
- this incarnation of the match() function will have set MATCH_CONDASSERT in
- md->match_function type, and one of these opcodes will be the first opcode
- that is processed. We use a local variable that is preserved over calls to
- match() to remember this case. */
-
- case OP_ASSERT:
- case OP_ASSERTBACK:
- save_mark = md->mark;
- if (md->match_function_type == MATCH_CONDASSERT)
- {
- condassert = TRUE;
- md->match_function_type = 0;
- }
- else condassert = FALSE;
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
- {
- mstart = md->start_match_ptr; /* In case \K reset it */
- break;
- }
- md->mark = save_mark;
-
- /* A COMMIT failure must fail the entire assertion, without trying any
- subsequent branches. */
-
- if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
-
- /* PCRE does not allow THEN to escape beyond an assertion; it
- is treated as NOMATCH. */
-
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode, 1);
- }
- while (*ecode == OP_ALT);
-
- if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
-
- /* If checking an assertion for a condition, return MATCH_MATCH. */
-
- if (condassert) RRETURN(MATCH_MATCH);
-
- /* Continue from after the assertion, updating the offsets high water
- mark, since extracts may have been taken during the assertion. */
-
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- ecode += 1 + LINK_SIZE;
- offset_top = md->end_offset_top;
- continue;
-
- /* Negative assertion: all branches must fail to match. Encountering SKIP,
- PRUNE, or COMMIT means we must assume failure without checking subsequent
- branches. */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK_NOT:
- save_mark = md->mark;
- if (md->match_function_type == MATCH_CONDASSERT)
- {
- condassert = TRUE;
- md->match_function_type = 0;
- }
- else condassert = FALSE;
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
- md->mark = save_mark;
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
- if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
- {
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- break;
- }
-
- /* PCRE does not allow THEN to escape beyond an assertion; it is treated
- as NOMATCH. */
-
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode,1);
- }
- while (*ecode == OP_ALT);
-
- if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
-
- ecode += 1 + LINK_SIZE;
- continue;
-
- /* Move the subject pointer back. This occurs only at the start of
- each branch of a lookbehind assertion. If we are too close to the start to
- move back, this match function fails. When working with UTF-8 we move
- back a number of characters, not bytes. */
-
- case OP_REVERSE:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- i = GET(ecode, 1);
- while (i-- > 0)
- {
- eptr--;
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- BACKCHAR(eptr);
- }
- }
- else
-#endif
-
- /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
-
- {
- eptr -= GET(ecode, 1);
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- }
-
- /* Save the earliest consulted character, then skip to next op code */
-
- if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
- ecode += 1 + LINK_SIZE;
- break;
-
- /* The callout item calls an external function, if one is provided, passing
- details of the match so far. This is mainly for debugging, though the
- function is able to force a failure. */
-
- case OP_CALLOUT:
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 2; /* Version 1 of the callout block */
- cb.callout_number = ecode[1];
- cb.offset_vector = md->offset_vector;
-#ifdef COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)md->start_subject;
-#else
- cb.subject = (PCRE_SPTR16)md->start_subject;
-#endif
- cb.subject_length = (int)(md->end_subject - md->start_subject);
- cb.start_match = (int)(mstart - md->start_subject);
- cb.current_position = (int)(eptr - md->start_subject);
- cb.pattern_position = GET(ecode, 2);
- cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
- cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last;
- cb.callout_data = md->callout_data;
- cb.mark = md->nomatch_mark;
- if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- }
- ecode += 2 + 2*LINK_SIZE;
- break;
-
- /* Recursion either matches the current regex, or some subexpression. The
- offset data is the offset to the starting bracket from the start of the
- whole pattern. (This is so that it works from duplicated subpatterns.)
-
- The state of the capturing groups is preserved over recursion, and
- re-instated afterwards. We don't know how many are started and not yet
- finished (offset_top records the completed total) so we just have to save
- all the potential data. There may be up to 65535 such values, which is too
- large to put on the stack, but using malloc for small numbers seems
- expensive. As a compromise, the stack is used when there are no more than
- REC_STACK_SAVE_MAX values to store; otherwise malloc is used.
-
- There are also other values that have to be saved. We use a chained
- sequence of blocks that actually live on the stack. Thanks to Robin Houston
- for the original version of this logic. It has, however, been hacked around
- a lot, so he is not to blame for the current way it works. */
-
- case OP_RECURSE:
- {
- recursion_info *ri;
- int recno;
-
- callpat = md->start_code + GET(ecode, 1);
- recno = (callpat == md->start_code)? 0 :
- GET2(callpat, 1 + LINK_SIZE);
-
- /* Check for repeating a recursion without advancing the subject pointer.
- This should catch convoluted mutual recursions. (Some simple cases are
- caught at compile time.) */
-
- for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
- if (recno == ri->group_num && eptr == ri->subject_position)
- RRETURN(PCRE_ERROR_RECURSELOOP);
-
- /* Add to "recursing stack" */
-
- new_recursive.group_num = recno;
- new_recursive.subject_position = eptr;
- new_recursive.prevrec = md->recursive;
- md->recursive = &new_recursive;
-
- /* Where to continue from afterwards */
-
- ecode += 1 + LINK_SIZE;
-
- /* Now save the offset data */
-
- new_recursive.saved_max = md->offset_end;
- if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
- new_recursive.offset_save = stacksave;
- else
- {
- new_recursive.offset_save =
- (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
- if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
- }
- memcpy(new_recursive.offset_save, md->offset_vector,
- new_recursive.saved_max * sizeof(int));
-
- /* OK, now we can do the recursion. After processing each alternative,
- restore the offset data. If there were nested recursions, md->recursive
- might be changed, so reset it before looping. */
-
- DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
- cbegroup = (*callpat >= OP_SBRA);
- do
- {
- if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
- md, eptrb, RM6);
- memcpy(md->offset_vector, new_recursive.offset_save,
- new_recursive.saved_max * sizeof(int));
- md->recursive = new_recursive.prevrec;
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
- {
- DPRINTF(("Recursion matched\n"));
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
-
- /* Set where we got to in the subject, and reset the start in case
- it was changed by \K. This *is* propagated back out of a recursion,
- for Perl compatibility. */
-
- eptr = md->end_match_ptr;
- mstart = md->start_match_ptr;
- goto RECURSION_MATCHED; /* Exit loop; end processing */
- }
-
- /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
- is treated as NOMATCH. */
-
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
- rrc != MATCH_COMMIT)
- {
- DPRINTF(("Recursion gave error %d\n", rrc));
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
- RRETURN(rrc);
- }
-
- md->recursive = &new_recursive;
- callpat += GET(callpat, 1);
- }
- while (*callpat == OP_ALT);
-
- DPRINTF(("Recursion didn't match\n"));
- md->recursive = new_recursive.prevrec;
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
- RRETURN(MATCH_NOMATCH);
- }
-
- RECURSION_MATCHED:
- break;
-
- /* An alternation is the end of a branch; scan along to find the end of the
- bracketed group and go to there. */
-
- case OP_ALT:
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- break;
-
- /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
- indicating that it may occur zero times. It may repeat infinitely, or not
- at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
- with fixed upper repeat limits are compiled as a number of copies, with the
- optional ones preceded by BRAZERO or BRAMINZERO. */
-
- case OP_BRAZERO:
- next = ecode + 1;
- RMATCH(eptr, next, offset_top, md, eptrb, RM10);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- do next += GET(next, 1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- break;
-
- case OP_BRAMINZERO:
- next = ecode + 1;
- do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode++;
- break;
-
- case OP_SKIPZERO:
- next = ecode+1;
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- break;
-
- /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
- here; just jump to the group, with allow_zero set TRUE. */
-
- case OP_BRAPOSZERO:
- op = *(++ecode);
- allow_zero = TRUE;
- if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
- goto POSSESSIVE_NON_CAPTURE;
-
- /* End of a group, repeated or non-repeating. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- case OP_KETRPOS:
- prev = ecode - GET(ecode, 1);
-
- /* If this was a group that remembered the subject start, in order to break
- infinite repeats of empty string matches, retrieve the subject start from
- the chain. Otherwise, set it NULL. */
-
- if (*prev >= OP_SBRA || *prev == OP_ONCE)
- {
- saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
- eptrb = eptrb->epb_prev; /* Backup to previous group */
- }
- else saved_eptr = NULL;
-
- /* If we are at the end of an assertion group or a non-capturing atomic
- group, stop matching and return MATCH_MATCH, but record the current high
- water mark for use by positive assertions. We also need to record the match
- start in case it was changed by \K. */
-
- if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
- *prev == OP_ONCE_NC)
- {
- md->end_match_ptr = eptr; /* For ONCE_NC */
- md->end_offset_top = offset_top;
- md->start_match_ptr = mstart;
- RRETURN(MATCH_MATCH); /* Sets md->mark */
- }
-
- /* For capturing groups we have to check the group number back at the start
- and if necessary complete handling an extraction by setting the offsets and
- bumping the high water mark. Whole-pattern recursion is coded as a recurse
- into group 0, so it won't be picked up here. Instead, we catch it when the
- OP_END is reached. Other recursion is handled here. We just have to record
- the current subject position and start match pointer and give a MATCH
- return. */
-
- if (*prev == OP_CBRA || *prev == OP_SCBRA ||
- *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
- {
- number = GET2(prev, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("end bracket %d", number);
- printf("\n");
-#endif
-
- /* Handle a recursively called group. */
-
- if (md->recursive != NULL && md->recursive->group_num == number)
- {
- md->end_match_ptr = eptr;
- md->start_match_ptr = mstart;
- RRETURN(MATCH_MATCH);
- }
-
- /* Deal with capturing */
-
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
- {
- /* If offset is greater than offset_top, it means that we are
- "skipping" a capturing group, and that group's offsets must be marked
- unset. In earlier versions of PCRE, all the offsets were unset at the
- start of matching, but this doesn't work because atomic groups and
- assertions can cause a value to be set that should later be unset.
- Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
- part of the atomic group, but this is not on the final matching path,
- so must be unset when 2 is set. (If there is no group 2, there is no
- problem, because offset_top will then be 2, indicating no capture.) */
-
- if (offset > offset_top)
- {
- int *iptr = md->offset_vector + offset_top;
- int *iend = md->offset_vector + offset;
- while (iptr < iend) *iptr++ = -1;
- }
-
- /* Now make the extraction */
-
- md->offset_vector[offset] =
- md->offset_vector[md->offset_end - number];
- md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
- if (offset_top <= offset) offset_top = offset + 2;
- }
- }
-
- /* For an ordinary non-repeating ket, just continue at this level. This
- also happens for a repeating ket if no characters were matched in the
- group. This is the forcible breaking of infinite loops as implemented in
- Perl 5.005. For a non-repeating atomic group that includes captures,
- establish a backup point by processing the rest of the pattern at a lower
- level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
- original OP_ONCE level, thereby bypassing intermediate backup points, but
- resetting any captures that happened along the way. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
- RRETURN(MATCH_ONCE);
- }
- ecode += 1 + LINK_SIZE; /* Carry on at this level */
- break;
- }
-
- /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
- and return the MATCH_KETRPOS. This makes it possible to do the repeats one
- at a time from the outer level, thus saving stack. */
-
- if (*ecode == OP_KETRPOS)
- {
- md->end_match_ptr = eptr;
- md->end_offset_top = offset_top;
- RRETURN(MATCH_KETRPOS);
- }
-
- /* The normal repeating kets try the rest of the pattern or restart from
- the preceding bracket, in the appropriate order. In the second case, we can
- use tail recursion to avoid using another stack frame, unless we have an
- an atomic group or an unlimited repeat of a group that can match an empty
- string. */
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM8);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
- RRETURN(MATCH_ONCE);
- }
- if (*prev >= OP_SBRA) /* Could match an empty string */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
- RRETURN(rrc);
- }
- ecode = prev;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
- if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev;
- RRETURN(MATCH_ONCE);
- }
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* Not multiline mode: start of subject assertion, unless notbol. */
-
- case OP_CIRC:
- if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
-
- /* Start of subject assertion */
-
- case OP_SOD:
- if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Multiline mode: start of subject unless notbol, or after any newline. */
-
- case OP_CIRCM:
- if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
- if (eptr != md->start_subject &&
- (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Start of match assertion */
-
- case OP_SOM:
- if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Reset the start of match point */
-
- case OP_SET_SOM:
- mstart = eptr;
- ecode++;
- break;
-
- /* Multiline mode: assert before any newline, or before end of subject
- unless noteol is set. */
-
- case OP_DOLLM:
- if (eptr < md->end_subject)
- {
- if (!IS_NEWLINE(eptr))
- {
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- else
- {
- if (md->noteol) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
- }
- ecode++;
- break;
-
- /* Not multiline mode: assert before a terminating newline or before end of
- subject unless noteol is set. */
-
- case OP_DOLL:
- if (md->noteol) RRETURN(MATCH_NOMATCH);
- if (!md->endonly) goto ASSERT_NL_OR_EOS;
-
- /* ... else fall through for endonly */
-
- /* End of subject assertion (\z) */
-
- case OP_EOD:
- if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
- ecode++;
- break;
-
- /* End of subject or ending \n assertion (\Z) */
-
- case OP_EODN:
- ASSERT_NL_OR_EOS:
- if (eptr < md->end_subject &&
- (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
- {
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Either at end of string or \n before end. */
-
- SCHECK_PARTIAL();
- ecode++;
- break;
-
- /* Word boundary assertions */
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- {
-
- /* Find out if the previous and current characters are "word" characters.
- It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
- be "non-word" characters. Remember the earliest consulted character for
- partial matching. */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- /* Get status of previous character */
-
- if (eptr == md->start_subject) prev_is_word = FALSE; else
- {
- PCRE_PUCHAR lastptr = eptr - 1;
- BACKCHAR(lastptr);
- if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
- GETCHAR(c, lastptr);
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- if (c == '_') prev_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- prev_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
-
- /* Get status of next character */
-
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- cur_is_word = FALSE;
- }
- else
- {
- GETCHAR(c, eptr);
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- if (c == '_') cur_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- cur_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
- }
- else
-#endif
-
- /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
- consistency with the behaviour of \w we do use it in this case. */
-
- {
- /* Get status of previous character */
-
- if (eptr == md->start_subject) prev_is_word = FALSE; else
- {
- if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- c = eptr[-1];
- if (c == '_') prev_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- prev_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- prev_is_word = MAX_255(eptr[-1])
- && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
- }
-
- /* Get status of next character */
-
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- cur_is_word = FALSE;
- }
- else
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- c = *eptr;
- if (c == '_') cur_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- cur_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- cur_is_word = MAX_255(*eptr)
- && ((md->ctypes[*eptr] & ctype_word) != 0);
- }
-
- /* Now see if the situation is what we want */
-
- if ((*ecode++ == OP_WORD_BOUNDARY)?
- cur_is_word == prev_is_word : cur_is_word != prev_is_word)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* Match any single character type except newline; have to take care with
- CRLF newlines and partial matching. */
-
- case OP_ANY:
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
-
- /* Fall through */
-
- /* Match any single character whatsoever. */
-
- case OP_ALLANY:
- if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
-#ifdef SUPPORT_UTF
- if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
-#endif
- ecode++;
- break;
-
- /* Match a single byte, even in UTF-8 mode. This opcode really does match
- any byte, even newline, independent of the setting of PCRE_DOTALL. */
-
- case OP_ANYBYTE:
- if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
- ecode++;
- break;
-
- case OP_NOT_DIGIT:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_digit) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_DIGIT:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_digit) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WHITESPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_space) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WHITESPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_space) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WORDCHAR:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_word) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WORDCHAR:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_word) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_ANYNL:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case 0x000d:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- }
- else if (*eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- ecode++;
- break;
-
- case OP_NOT_HSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
- case OP_HSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- ecode++;
- break;
-
- case OP_NOT_VSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
- case OP_VSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- ecode++;
- break;
-
-#ifdef SUPPORT_UCP
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs. */
-
- case OP_PROP:
- case OP_NOTPROP:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- {
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
-
- switch(ecode[1])
- {
- case PT_ANY:
- if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_LAMP:
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_GC:
- if ((ecode[2] != PRIV(ucp_gentype)[chartype]) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PC:
- if ((ecode[2] != chartype) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SC:
- if ((ecode[2] != UCD_SCRIPT(c)) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* These are specials */
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SPACE: /* Perl space */
- if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PXSPACE: /* POSIX space */
- if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* This should never occur */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- ecode += 3;
- }
- break;
-
- /* Match an extended Unicode sequence. We will get here only if the support
- is in the binary; otherwise a compile-time error occurs. */
-
- case OP_EXTUNI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr += len;
- }
- CHECK_PARTIAL();
- ecode++;
- break;
-#endif
-
-
- /* Match a back reference, possibly repeatedly. Look past the end of the
- item to see if there is repeat information following. The code is similar
- to that for character classes, but repeated for efficiency. Then obey
- similar code to character type repeats - written out again for speed.
- However, if the referenced string is the empty string, always treat
- it as matched, any number of times (otherwise there could be infinite
- loops). */
-
- case OP_REF:
- case OP_REFI:
- caseless = op == OP_REFI;
- offset = GET2(ecode, 1) << 1; /* Doubled ref number */
- ecode += 1 + IMM2_SIZE;
-
- /* If the reference is unset, there are two possibilities:
-
- (a) In the default, Perl-compatible state, set the length negative;
- this ensures that every attempt at a match fails. We can't just fail
- here, because of the possibility of quantifiers with zero minima.
-
- (b) If the JavaScript compatibility flag is set, set the length to zero
- so that the back reference matches an empty string.
-
- Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
-
- if (offset >= offset_top || md->offset_vector[offset] < 0)
- length = (md->jscript_compat)? 0 : -1;
- else
- length = md->offset_vector[offset+1] - md->offset_vector[offset];
-
- /* Set up for repetition, or handle the non-repeated case */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (length == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += length;
- continue; /* With the main loop */
- }
-
- /* Handle repeated back references. If the length of the reference is
- zero, just continue with the main loop. If the length is negative, it
- means the reference is unset in non-Java-compatible mode. If the minimum is
- zero, we can continue at the same level without recursion. For any other
- minimum, carrying on will result in NOMATCH. */
-
- if (length == 0) continue;
- if (length < 0 && min == 0) continue;
-
- /* First, ensure the minimum number of matches are present. We get back
- the length of the reference string explicitly rather than passing the
- address of eptr, so that eptr can be a register variable. */
-
- for (i = 1; i <= min; i++)
- {
- int slength;
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (slength == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += slength;
- }
-
- /* If min = max, continue at the same level without recursion.
- They are not both allowed to be zero. */
-
- if (min == max) continue;
-
- /* If minimizing, keep trying and advancing the pointer */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- int slength;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (slength == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += slength;
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest string and work backwards */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- int slength;
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- /* Can't use CHECK_PARTIAL because we don't want to update eptr in
- the soft partial matching case. */
-
- if (slength == -2 && md->partial != 0 &&
- md->end_subject > md->start_used_ptr)
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
- }
- eptr += slength;
- }
-
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr -= length;
- }
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* Match a bit-mapped character class, possibly repeatedly. This op code is
- used when all the characters in the class have values in the range 0-255,
- and either the matching is caseful, or the characters are in the range
- 0-127 when UTF-8 processing is enabled. The only difference between
- OP_CLASS and OP_NCLASS occurs when a data character outside the range is
- encountered.
-
- First, look past the end of the item to see if there is repeat information
- following. Then obey similar code to character type repeats - written out
- again for speed. */
-
- case OP_NCLASS:
- case OP_CLASS:
- {
- /* The data variable is saved across frames, so the byte map needs to
- be stored there. */
-#define BYTE_MAP ((pcre_uint8 *)data)
- data = ecode + 1; /* Save for matching */
- ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- c = *eptr++;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- c = *eptr++;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c > 255)
- {
- if (op == OP_CLASS) break;
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
- eptr += len;
- }
- for (;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) break;
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
- eptr++;
- }
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
-#undef BYTE_MAP
- }
- /* Control never gets here */
-
-
- /* Match an extended character class. This opcode is encountered only
- when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
- mode, because Unicode properties are supported in non-UTF-8 mode. */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- {
- data = ecode + 1 + LINK_SIZE; /* Save for matching */
- ecode += GET(ecode, 1); /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
-#ifdef SUPPORT_UTF
- GETCHARLENTEST(c, eptr, len);
-#else
- c = *eptr;
-#endif
- if (!PRIV(xclass)(c, data, utf)) break;
- eptr += len;
- }
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
-#ifdef SUPPORT_UTF
- if (utf) BACKCHAR(eptr);
-#endif
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Control never gets here */
- }
-#endif /* End of XCLASS */
-
- /* Match a single character, casefully */
-
- case OP_CHAR:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
- if (length > md->end_subject - eptr)
- {
- CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- /* Not UTF mode */
- {
- if (md->end_subject - eptr < 1)
- {
- SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a single character, caselessly. If we are at the end of the
- subject, give up immediately. */
-
- case OP_CHARI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
-
- /* If the pattern character's value is < 128, we have only one byte, and
- we know that its other case must also be one byte long, so we can use the
- fast lookup table. We know that there is at least one byte left in the
- subject. */
-
- if (fc < 128)
- {
- if (md->lcc[fc]
- != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
- ecode++;
- eptr++;
- }
-
- /* Otherwise we must pick up the subject character. Note that we cannot
- use the value of "length" to check for sufficient bytes left, because the
- other case of the character may have more or fewer bytes. */
-
- else
- {
- unsigned int dc;
- GETCHARINC(dc, eptr);
- ecode += length;
-
- /* If we have Unicode property support, we can use it to test the other
- case of the character, if there is one. */
-
- if (fc != dc)
- {
-#ifdef SUPPORT_UCP
- if (dc != UCD_OTHERCASE(fc))
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- }
- else
-#endif /* SUPPORT_UTF */
-
- /* Not UTF mode */
- {
- if (TABLE_GET(ecode[1], md->lcc, ecode[1])
- != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
- eptr++;
- ecode += 2;
- }
- break;
-
- /* Match a single character repeatedly. */
-
- case OP_EXACT:
- case OP_EXACTI:
- min = max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSUPTO:
- case OP_POSUPTOI:
- possessive = TRUE;
- /* Fall through */
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
- ecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSSTAR:
- case OP_POSSTARI:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSPLUS:
- case OP_POSPLUSI:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSQUERY:
- case OP_POSQUERYI:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATCHAR;
-
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-character matches. */
-
- REPEATCHAR:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- charptr = ecode;
- GETCHARLEN(fc, ecode, length);
- ecode += length;
-
- /* Handle multibyte character matching specially here. There is
- support for caseless matching if UCP support is present. */
-
- if (length > 1)
- {
-#ifdef SUPPORT_UCP
- unsigned int othercase;
- if (op >= OP_STARI && /* Caseless */
- (othercase = UCD_OTHERCASE(fc)) != fc)
- oclength = PRIV(ord2utf)(othercase, occhars);
- else oclength = 0;
-#endif /* SUPPORT_UCP */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- break;
- }
- }
-
- if (possessive) continue;
-
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
-#ifdef SUPPORT_UCP
- eptr--;
- BACKCHAR(eptr);
-#else /* without SUPPORT_UCP */
- eptr -= length;
-#endif /* SUPPORT_UCP */
- }
- }
- /* Control never gets here */
- }
-
- /* If the length of a UTF-8 character is 1, we fall through here, and
- obey the code as for non-UTF-8 characters below, though in this case the
- value of fc will always be < 128. */
- }
- else
-#endif /* SUPPORT_UTF */
- /* When not in UTF-8 mode, load a single-byte character. */
- fc = *ecode++;
-
- /* The value of fc at this point is always one character, though we may
- or may not be in UTF mode. The code is duplicated for the caseless and
- caseful cases, for speed, since matching characters is likely to be quite
- common. First, ensure the minimum number of matches are present. If min =
- max, continue at the same level without recursing. Otherwise, if
- minimizing, keep trying the rest of the expression and advancing one
- matching character if failing, up to the maximum. Alternatively, if
- maximizing, find the maximum number of characters and work backwards. */
-
- DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, (char *)eptr));
-
- if (op >= OP_STARI) /* Caseless */
- {
-#ifdef COMPILE_PCRE8
- /* fc must be < 128 if UTF is enabled. */
- foc = md->fcc[fc];
-#else
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (utf && fc > 127)
- foc = UCD_OTHERCASE(fc);
-#else
- if (utf && fc > 127)
- foc = fc;
-#endif /* SUPPORT_UCP */
- else
-#endif /* SUPPORT_UTF */
- foc = TABLE_GET(fc, md->fcc, fc);
-#endif /* COMPILE_PCRE8 */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- if (min == max) continue;
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc != *eptr && foc != *eptr) break;
- eptr++;
- }
-
- if (possessive) continue;
-
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons (includes all multi-byte characters) */
-
- else
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc != *eptr) break;
- eptr++;
- }
- if (possessive) continue;
-
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a negated single one-byte character. The character we are
- checking can be multibyte. */
-
- case OP_NOT:
- case OP_NOTI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int ch, och;
-
- ecode++;
- GETCHARINC(ch, ecode);
- GETCHARINC(c, eptr);
-
- if (op == OP_NOT)
- {
- if (ch == c) RRETURN(MATCH_NOMATCH);
- }
- else
- {
-#ifdef SUPPORT_UCP
- if (ch > 127)
- och = UCD_OTHERCASE(ch);
-#else
- if (ch > 127)
- och = ch;
-#endif /* SUPPORT_UCP */
- else
- och = TABLE_GET(ch, md->fcc, ch);
- if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- {
- unsigned int ch = ecode[1];
- c = *eptr++;
- if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
- RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a negated single one-byte character repeatedly. This is almost a
- repeat of the code for a repeated single character, but I haven't found a
- nice way of commoning these up that doesn't require a test of the
- positive/negative option for each character match. Maybe that wouldn't add
- very much to the time taken, but character matching *is* what this is all
- about... */
-
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- min = max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-byte matches. */
-
- REPEATNOTCHAR:
- GETCHARINCTEST(fc, ecode);
-
- /* The code is duplicated for the caseless and caseful cases, for speed,
- since matching characters is likely to be quite common. First, ensure the
- minimum number of matches are present. If min = max, continue at the same
- level without recursing. Otherwise, if minimizing, keep trying the rest of
- the expression and advancing one matching character if failing, up to the
- maximum. Alternatively, if maximizing, find the maximum number of
- characters and work backwards. */
-
- DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, (char *)eptr));
-
- if (op >= OP_NOTSTARI) /* Caseless */
- {
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (utf && fc > 127)
- foc = UCD_OTHERCASE(fc);
-#else
- if (utf && fc > 127)
- foc = fc;
-#endif /* SUPPORT_UCP */
- else
-#endif /* SUPPORT_UTF */
- foc = TABLE_GET(fc, md->fcc, fc);
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, eptr, len);
- if (fc == d || (unsigned int)foc == d) break;
- eptr += len;
- }
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc == *eptr || foc == *eptr) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons */
-
- else
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- unsigned int d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, eptr, len);
- if (fc == d) break;
- eptr += len;
- }
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc == *eptr) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a single character type repeatedly; several different opcodes
- share code. This is very similar to the code for single characters, but we
- repeat it in the interests of efficiency. */
-
- case OP_TYPEEXACT:
- min = max = GET2(ecode, 1);
- minimize = TRUE;
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_TYPEMINUPTO;
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEPOSSTAR:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSPLUS:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSQUERY:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSUPTO:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- c = *ecode++ - OP_TYPESTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single character type matches. Note that
- in UTF-8 mode, '.' matches a character of any length, but for the other
- character types, the valid characters are all one-byte long. */
-
- REPEATTYPE:
- ctype = *ecode++; /* Code for the character type */
-
-#ifdef SUPPORT_UCP
- if (ctype == OP_PROP || ctype == OP_NOTPROP)
- {
- prop_fail_result = ctype == OP_NOTPROP;
- prop_type = *ecode++;
- prop_value = *ecode++;
- }
- else prop_type = -1;
-#endif
-
- /* First, ensure the minimum number of matches are present. Use inline
- code for maximizing the speed, and do the type test once at the start
- (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
- is tidier. Also separate the UCP code, which can be the same for both UTF-8
- and single-bytes. */
-
- if (min > 0)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- }
- break;
-
- case PT_LAMP:
- for (i = 1; i <= min; i++)
- {
- int chartype;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_GC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_ALNUM:
- for (i = 1; i <= min; i++)
- {
- int category;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SPACE: /* Perl space */
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PXSPACE: /* POSIX space */
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_WORD:
- for (i = 1; i <= min; i++)
- {
- int category;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* This should not occur */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr += len;
- }
- CHECK_PARTIAL();
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-/* Handle all other cases when the coding is UTF-8 */
-
-#ifdef SUPPORT_UTF
- if (utf) switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_ALLANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_ANYBYTE:
- if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
- eptr += min;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- } /* End switch(ctype) */
-
- else
-#endif /* SUPPORT_UTF */
-
- /* Code for the non-UTF-8 case for minimum matching of operators other
- than OP_PROP and OP_NOTPROP. */
-
- switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- if (eptr > md->end_subject - min)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += min;
- break;
-
- case OP_ANYBYTE:
- if (eptr > md->end_subject - min)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += min;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
-#ifdef COMPILE_PCRE16
- case 0x2028:
- case 0x2029:
-#endif
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
-#ifdef COMPILE_PCRE16
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
-#ifdef COMPILE_PCRE16
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
-#ifdef COMPILE_PCRE16
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
-#ifdef COMPILE_PCRE16
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* If min = max, continue at the same level without recursing */
-
- if (min == max) continue;
-
- /* If minimizing, we have to test the rest of the pattern before each
- subsequent match. Again, separate the UTF-8 case for speed, and also
- separate the UCP cases. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_LAMP:
- for (fi = min;; fi++)
- {
- int chartype;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_GC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_ALNUM:
- for (fi = min;; fi++)
- {
- int category;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SPACE: /* Perl space */
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PXSPACE: /* POSIX space */
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_WORD:
- for (fi = min;; fi++)
- {
- int category;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L ||
- category == ucp_N ||
- c == CHAR_UNDERSCORE)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* This should never occur */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr += len;
- }
- CHECK_PARTIAL();
- }
- }
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (ctype == OP_ANY && IS_NEWLINE(eptr))
- RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (ctype == OP_ANY && IS_NEWLINE(eptr))
- RRETURN(MATCH_NOMATCH);
- c = *eptr++;
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
-#ifdef COMPILE_PCRE16
- case 0x2028:
- case 0x2029:
-#endif
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
-#ifdef COMPILE_PCRE16
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
-#ifdef COMPILE_PCRE16
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
-#endif
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
-#ifdef COMPILE_PCRE16
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
-#ifdef COMPILE_PCRE16
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
-#endif
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, it is worth using inline code for speed, doing the type
- test once at the start (i.e. keep it out of the loop). Again, keep the
- UTF-8 and UCP stuff separate. */
-
- else
- {
- pp = eptr; /* Remember where we started */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if (prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_LAMP:
- for (i = min; i < max; i++)
- {
- int chartype;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_GC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_PC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_SC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_ALNUM:
- for (i = min; i < max; i++)
- {
- int category;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_SPACE: /* Perl space */
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_PXSPACE: /* POSIX space */
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_WORD:
- for (i = min; i < max; i++)
- {
- int category;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N ||
- c == CHAR_UNDERSCORE) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- if (utf) BACKCHAR(eptr);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- if (UCD_CATEGORY(c) == ucp_M) break;
- eptr += len;
- while (eptr < md->end_subject)
- {
- len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr += len;
- }
- CHECK_PARTIAL();
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
-
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- for (;;) /* Move back over one extended */
- {
- if (!utf) c = *eptr; else
- {
- BACKCHAR(eptr);
- GETCHAR(c, eptr);
- }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr--;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- switch(ctype)
- {
- case OP_ANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
-
- /* Handle unlimited UTF-8 repeat */
-
- else
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
- break;
-
- case OP_ALLANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
- else
- {
- eptr = md->end_subject; /* Unlimited UTF-8 repeat */
- SCHECK_PARTIAL();
- }
- break;
-
- /* The byte case is the same as non-UTF8 */
-
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- {
- eptr = md->end_subject;
- SCHECK_PARTIAL();
- }
- else eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c == 0x000d)
- {
- if (++eptr >= md->end_subject) break;
- if (*eptr == 0x000a) eptr++;
- }
- else
- {
- if (c != 0x000a &&
- (md->bsr_anycrlf ||
- (c != 0x000b && c != 0x000c &&
- c != 0x0085 && c != 0x2028 && c != 0x2029)))
- break;
- eptr += len;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- default: gotspace = FALSE; break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- gotspace = TRUE;
- break;
- }
- if (gotspace == (ctype == OP_NOT_HSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- default: gotspace = FALSE; break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- gotspace = TRUE;
- break;
- }
- if (gotspace == (ctype == OP_NOT_VSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
- eptr+= len;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run. If possessive, we are
- done (no backing up). Otherwise, match at this position; anything other
- than no match is immediately returned. For nomatch, back up one
- character, unless we are matching \R and the last thing matched was
- \r\n, in which case, back up two bytes. */
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
- eptr[-1] == '\r') eptr--;
- }
- }
- else
-#endif /* SUPPORT_UTF */
- /* Not UTF mode */
- {
- switch(ctype)
- {
- case OP_ANY:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- {
- eptr = md->end_subject;
- SCHECK_PARTIAL();
- }
- else eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c == 0x000d)
- {
- if (++eptr >= md->end_subject) break;
- if (*eptr == 0x000a) eptr++;
- }
- else
- {
- if (c != 0x000a && (md->bsr_anycrlf ||
- (c != 0x000b && c != 0x000c && c != 0x0085
-#ifdef COMPILE_PCRE16
- && c != 0x2028 && c != 0x2029
-#endif
- ))) break;
- eptr++;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c == 0x09 || c == 0x20 || c == 0xa0
-#ifdef COMPILE_PCRE16
- || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
- || c == 0x202f || c == 0x205f || c == 0x3000
-#endif
- ) break;
- eptr++;
- }
- break;
-
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c != 0x09 && c != 0x20 && c != 0xa0
-#ifdef COMPILE_PCRE16
- && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
- && c != 0x202f && c != 0x205f && c != 0x3000
-#endif
- ) break;
- eptr++;
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
-#ifdef COMPILE_PCRE16
- || c == 0x2028 || c == 0x2029
-#endif
- ) break;
- eptr++;
- }
- break;
-
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
-#ifdef COMPILE_PCRE16
- && c != 0x2028 && c != 0x2029
-#endif
- ) break;
- eptr++;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
- eptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
- eptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
- eptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
- eptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
- eptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
- eptr++;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run. If possessive, we are
- done (no backing up). Otherwise, match at this position; anything other
- than no match is immediately returned. For nomatch, back up one
- character (byte), unless we are matching \R and the last thing matched
- was \r\n, in which case, back up two bytes. */
-
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
- eptr[-1] == '\r') eptr--;
- }
- }
-
- /* Get here if we can't make it match with any permitted repetitions */
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* There's been some horrible disaster. Arrival here can only mean there is
- something seriously wrong in the code above or the OP_xxx definitions. */
-
- default:
- DPRINTF(("Unknown opcode %d\n", *ecode));
- RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
- }
-
- /* Do not stick any code in here without much thought; it is assumed
- that "continue" in the code above comes out to here to repeat the main
- loop. */
-
- } /* End of main loop */
-/* Control never reaches here */
-
-
-/* When compiling to use the heap rather than the stack for recursive calls to
-match(), the RRETURN() macro jumps here. The number that is saved in
-frame->Xwhere indicates which label we actually want to return to. */
-
-#ifdef NO_RECURSE
-#define LBL(val) case val: goto L_RM##val;
-HEAP_RETURN:
-switch (frame->Xwhere)
- {
- LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
- LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
- LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
- LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
- LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
- LBL(65) LBL(66)
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- LBL(21)
-#endif
-#ifdef SUPPORT_UTF
- LBL(16) LBL(18) LBL(20)
- LBL(22) LBL(23) LBL(28) LBL(30)
- LBL(32) LBL(34) LBL(42) LBL(46)
-#ifdef SUPPORT_UCP
- LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
- LBL(59) LBL(60) LBL(61) LBL(62)
-#endif /* SUPPORT_UCP */
-#endif /* SUPPORT_UTF */
- default:
- DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
-
-printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
-
- return PCRE_ERROR_INTERNAL;
- }
-#undef LBL
-#endif /* NO_RECURSE */
-}
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-Undefine all the macros that were defined above to handle this. */
-
-#ifdef NO_RECURSE
-#undef eptr
-#undef ecode
-#undef mstart
-#undef offset_top
-#undef eptrb
-#undef flags
-
-#undef callpat
-#undef charptr
-#undef data
-#undef next
-#undef pp
-#undef prev
-#undef saved_eptr
-
-#undef new_recursive
-
-#undef cur_is_word
-#undef condition
-#undef prev_is_word
-
-#undef ctype
-#undef length
-#undef max
-#undef min
-#undef number
-#undef offset
-#undef op
-#undef save_capture_last
-#undef save_offset1
-#undef save_offset2
-#undef save_offset3
-#undef stacksave
-
-#undef newptrb
-
-#endif
-
-/* These two are defined as macros in both cases */
-
-#undef fc
-#undef fi
-
-/***************************************************************************
-***************************************************************************/
-
-
-#ifdef NO_RECURSE
-/*************************************************
-* Release allocated heap frames *
-*************************************************/
-
-/* This function releases all the allocated frames. The base frame is on the
-machine stack, and so must not be freed.
-
-Argument: the address of the base frame
-Returns: nothing
-*/
-
-static void
-release_match_heapframes (heapframe *frame_base)
-{
-heapframe *nextframe = frame_base->Xnextframe;
-while (nextframe != NULL)
- {
- heapframe *oldframe = nextframe;
- nextframe = nextframe->Xnextframe;
- (PUBL(stack_free))(oldframe);
- }
-}
-#endif
-
-
-/*************************************************
-* Execute a Regular Expression *
-*************************************************/
-
-/* This function applies a compiled re to a subject string and picks out
-portions of the string if it matches. Two elements in the vector are set for
-each substring: the offsets to the start and end of the substring.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- offsets points to a vector of ints to be filled in with offsets
- offsetcount the number of elements in the vector
-
-Returns: > 0 => success; value is the number of elements filled in
- = 0 => success, but offsets is not big enough
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
- PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
- PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-#endif
-{
-int rc, ocount, arg_offset_max;
-int newline;
-BOOL using_temporary_offsets = FALSE;
-BOOL anchored;
-BOOL startline;
-BOOL firstline;
-BOOL utf;
-BOOL has_first_char = FALSE;
-BOOL has_req_char = FALSE;
-pcre_uchar first_char = 0;
-pcre_uchar first_char2 = 0;
-pcre_uchar req_char = 0;
-pcre_uchar req_char2 = 0;
-match_data match_block;
-match_data *md = &match_block;
-const pcre_uint8 *tables;
-const pcre_uint8 *start_bits = NULL;
-PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
-PCRE_PUCHAR end_subject;
-PCRE_PUCHAR start_partial = NULL;
-PCRE_PUCHAR req_char_ptr = start_match - 1;
-
-const pcre_study_data *study;
-const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
-
-#ifdef NO_RECURSE
-heapframe frame_zero;
-frame_zero.Xprevframe = NULL; /* Marks the top level */
-frame_zero.Xnextframe = NULL; /* None are allocated yet */
-md->match_frames_base = &frame_zero;
-#endif
-
-/* Check for the special magic call that measures the size of the stack used
-per recursive call of match(). Without the funny casting for sizeof, a Windows
-compiler gave this error: "unary minus operator applied to unsigned type,
-result still unsigned". Hopefully the cast fixes that. */
-
-if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
- start_offset == -999)
-#ifdef NO_RECURSE
- return -((int)sizeof(heapframe));
-#else
- return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
-#endif
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
- return PCRE_ERROR_NULL;
-if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
-if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-/* These two settings are used in the code for checking a UTF-8 string that
-follows immediately afterwards. Other values in the md block are used only
-during "normal" pcre_exec() processing, not when the JIT support is in use,
-so they are set up later. */
-
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-utf = md->utf = (re->options & PCRE_UTF8) != 0;
-md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
- ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
-
-/* Check a UTF-8 string if required. Pass back the character offset and error
-code for an invalid string if a results vector is available. */
-
-#ifdef SUPPORT_UTF
-if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- int erroroffset;
- int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
- if (errorcode != 0)
- {
- if (offsetcount >= 2)
- {
- offsets[0] = erroroffset;
- offsets[1] = errorcode;
- }
-#ifdef COMPILE_PCRE16
- return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
- PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
-#else
- return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
-#endif
- }
-
- /* Check that a start_offset points to the start of a UTF character. */
- if (start_offset > 0 && start_offset < length &&
- NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
- return PCRE_ERROR_BADUTF8_OFFSET;
- }
-#endif
-
-/* If the pattern was successfully studied with JIT support, run the JIT
-executable instead of the rest of this function. Most options must be set at
-compile time for the JIT code to be usable. Fallback to the normal code path if
-an unsupported flag is set. */
-
-#ifdef SUPPORT_JIT
-if (extra_data != NULL
- && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
- PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
- && extra_data->executable_jit != NULL
- && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
- PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
- PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
- {
- rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
- start_offset, options, offsets, offsetcount);
-
- /* PCRE_ERROR_NULL means that the selected normal or partial matching
- mode is not compiled. In this case we simply fallback to interpreter. */
-
- if (rc != PCRE_ERROR_NULL) return rc;
- }
-#endif
-
-/* Carry on with non-JIT matching. This information is for finding all the
-numbers associated with a given name, for condition testing. */
-
-md->name_table = (pcre_uchar *)re + re->name_table_offset;
-md->name_count = re->name_count;
-md->name_entry_size = re->name_entry_size;
-
-/* Fish out the optional data from the extra_data structure, first setting
-the default values. */
-
-study = NULL;
-md->match_limit = MATCH_LIMIT;
-md->match_limit_recursion = MATCH_LIMIT_RECURSION;
-md->callout_data = NULL;
-
-/* The table pointer is always in native byte order. */
-
-tables = re->tables;
-
-if (extra_data != NULL)
- {
- unsigned int flags = extra_data->flags;
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
- md->match_limit = extra_data->match_limit;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
- md->match_limit_recursion = extra_data->match_limit_recursion;
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
- md->callout_data = extra_data->callout_data;
- if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
- }
-
-/* If the exec call supplied NULL for tables, use the inbuilt ones. This
-is a feature that makes it possible to save compiled regex and re-use them
-in other programs later. */
-
-if (tables == NULL) tables = PRIV(default_tables);
-
-/* Set up other data */
-
-anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
-startline = (re->flags & PCRE_STARTLINE) != 0;
-firstline = (re->options & PCRE_FIRSTLINE) != 0;
-
-/* The code starts after the real_pcre block and the capture name table. */
-
-md->start_code = (const pcre_uchar *)re + re->name_table_offset +
- re->name_count * re->name_entry_size;
-
-md->start_subject = (PCRE_PUCHAR)subject;
-md->start_offset = start_offset;
-md->end_subject = md->start_subject + length;
-end_subject = md->end_subject;
-
-md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-md->use_ucp = (re->options & PCRE_UCP) != 0;
-md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
-md->ignore_skip_arg = FALSE;
-
-/* Some options are unpacked into BOOL variables in the hope that testing
-them will be faster than individual option bits. */
-
-md->notbol = (options & PCRE_NOTBOL) != 0;
-md->noteol = (options & PCRE_NOTEOL) != 0;
-md->notempty = (options & PCRE_NOTEMPTY) != 0;
-md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
-
-md->hitend = FALSE;
-md->mark = md->nomatch_mark = NULL; /* In case never set */
-
-md->recursive = NULL; /* No recursion at top level */
-md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
-
-md->lcc = tables + lcc_offset;
-md->fcc = tables + fcc_offset;
-md->ctypes = tables + ctypes_offset;
-
-/* Handle different \R options. */
-
-switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- case 0:
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
- md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
- else
-#ifdef BSR_ANYCRLF
- md->bsr_anycrlf = TRUE;
-#else
- md->bsr_anycrlf = FALSE;
-#endif
- break;
-
- case PCRE_BSR_ANYCRLF:
- md->bsr_anycrlf = TRUE;
- break;
-
- case PCRE_BSR_UNICODE:
- md->bsr_anycrlf = FALSE;
- break;
-
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-/* Handle different types of newline. The three bits give eight cases. If
-nothing is set at run time, whatever was used at compile time applies. */
-
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
- (pcre_uint32)options) & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Compile-time default */
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-if (newline == -2)
- {
- md->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- md->nltype = NLTYPE_ANY;
- }
-else
- {
- md->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- md->nllen = 2;
- md->nl[0] = (newline >> 8) & 255;
- md->nl[1] = newline & 255;
- }
- else
- {
- md->nllen = 1;
- md->nl[0] = newline;
- }
- }
-
-/* Partial matching was originally supported only for a restricted set of
-regexes; from release 8.00 there are no restrictions, but the bits are still
-defined (though never set). So there's no harm in leaving this code. */
-
-if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
- return PCRE_ERROR_BADPARTIAL;
-
-/* If the expression has got more back references than the offsets supplied can
-hold, we get a temporary chunk of working store to use during the matching.
-Otherwise, we can use the vector supplied, rounding down its size to a multiple
-of 3. */
-
-ocount = offsetcount - (offsetcount % 3);
-arg_offset_max = (2*ocount)/3;
-
-if (re->top_backref > 0 && re->top_backref >= ocount/3)
- {
- ocount = re->top_backref * 3 + 3;
- md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
- if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
- using_temporary_offsets = TRUE;
- DPRINTF(("Got memory to hold back references\n"));
- }
-else md->offset_vector = offsets;
-
-md->offset_end = ocount;
-md->offset_max = (2*ocount)/3;
-md->offset_overflow = FALSE;
-md->capture_last = -1;
-
-/* Reset the working variable associated with each extraction. These should
-never be used unless previously set, but they get saved and restored, and so we
-initialize them to avoid reading uninitialized locations. Also, unset the
-offsets for the matched string. This is really just for tidiness with callouts,
-in case they inspect these fields. */
-
-if (md->offset_vector != NULL)
- {
- int *iptr = md->offset_vector + ocount;
- int *iend = iptr - re->top_bracket;
- if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
- while (--iptr >= iend) *iptr = -1;
- md->offset_vector[0] = md->offset_vector[1] = -1;
- }
-
-/* Set up the first character to match, if available. The first_char value is
-never set for an anchored regular expression, but the anchoring may be forced
-at run time, so we have to test for anchoring. The first char may be unset for
-an unanchored pattern, of course. If there's no first char and the pattern was
-studied, there may be a bitmap of possible first characters. */
-
-if (!anchored)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- has_first_char = TRUE;
- first_char = first_char2 = (pcre_uchar)(re->first_char);
- if ((re->flags & PCRE_FCH_CASELESS) != 0)
- {
- first_char2 = TABLE_GET(first_char, md->fcc, first_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && first_char > 127)
- first_char2 = UCD_OTHERCASE(first_char);
-#endif
- }
- }
- else
- if (!startline && study != NULL &&
- (study->flags & PCRE_STUDY_MAPPED) != 0)
- start_bits = study->start_bits;
- }
-
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- has_req_char = TRUE;
- req_char = req_char2 = (pcre_uchar)(re->req_char);
- if ((re->flags & PCRE_RCH_CASELESS) != 0)
- {
- req_char2 = TABLE_GET(req_char, md->fcc, req_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && req_char > 127)
- req_char2 = UCD_OTHERCASE(req_char);
-#endif
- }
- }
-
-
-/* ==========================================================================*/
-
-/* Loop for handling unanchored repeated matching attempts; for anchored regexs
-the loop runs just once. */
-
-for(;;)
- {
- PCRE_PUCHAR save_end_subject = end_subject;
- PCRE_PUCHAR new_start_match;
-
- /* If firstline is TRUE, the start of the match is constrained to the first
- line of a multiline string. That is, the match must be before or at the first
- newline. Implement this by temporarily adjusting end_subject so that we stop
- scanning at a newline. If the match fails at the newline, later code breaks
- this loop. */
-
- if (firstline)
- {
- PCRE_PUCHAR t = start_match;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (t < md->end_subject && !IS_NEWLINE(t))
- {
- t++;
- ACROSSCHAR(t < end_subject, *t, t++);
- }
- }
- else
-#endif
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* There are some optimizations that avoid running the match if a known
- starting point is not found, or if a known later character is not present.
- However, there is an option that disables these, for testing and for ensuring
- that all callouts do actually occur. The option can be set in the regex by
- (*NO_START_OPT) or passed in match-time options. */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
- {
- /* Advance to a unique first char if there is one. */
-
- if (has_first_char)
- {
- if (first_char != first_char2)
- while (start_match < end_subject &&
- *start_match != first_char && *start_match != first_char2)
- start_match++;
- else
- while (start_match < end_subject && *start_match != first_char)
- start_match++;
- }
-
- /* Or to just after a linebreak for a multiline match */
-
- else if (startline)
- {
- if (start_match > md->start_subject + start_offset)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- {
- start_match++;
- ACROSSCHAR(start_match < end_subject, *start_match,
- start_match++);
- }
- }
- else
-#endif
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- start_match++;
-
- /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
- and we are now at a LF, advance the match position by one more character.
- */
-
- if (start_match[-1] == CHAR_CR &&
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
- start_match < end_subject &&
- *start_match == CHAR_NL)
- start_match++;
- }
- }
-
- /* Or to a non-unique first byte after study */
-
- else if (start_bits != NULL)
- {
- while (start_match < end_subject)
- {
- unsigned int c = *start_match;
-#ifndef COMPILE_PCRE8
- if (c > 255) c = 255;
-#endif
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- {
- start_match++;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- /* In non 8-bit mode, the iteration will stop for
- characters > 255 at the beginning or not stop at all. */
- if (utf)
- ACROSSCHAR(start_match < end_subject, *start_match,
- start_match++);
-#endif
- }
- else break;
- }
- }
- } /* Starting optimizations */
-
- /* Restore fudged end_subject */
-
- end_subject = save_end_subject;
-
- /* The following two optimizations are disabled for partial matching or if
- disabling is explicitly requested. */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
- {
- /* If the pattern was studied, a minimum subject length may be set. This is
- a lower bound; no actual string of that length may actually match the
- pattern. Although the value is, strictly, in characters, we treat it as
- bytes to avoid spending too much time in this optimization. */
-
- if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
- (pcre_uint32)(end_subject - start_match) < study->minlength)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If req_char is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_char
- must be later in the subject; otherwise the test starts at the match point.
- This optimization can save a huge amount of backtracking in patterns with
- nested unlimited repeats that aren't going to match. Writing separate code
- for cased/caseless versions makes it go faster, as does using an
- autoincrement and backing off on a match.
-
- HOWEVER: when the subject string is very, very long, searching to its end
- can take a long time, and give bad performance on quite ordinary patterns.
- This showed up when somebody was matching something like /^\d+C/ on a
- 32-megabyte string... so we don't do this when the string is sufficiently
- long. */
-
- if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
- {
- PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
-
- if (p > req_char_ptr)
- {
- if (req_char != req_char2)
- {
- while (p < end_subject)
- {
- int pp = *p++;
- if (pp == req_char || pp == req_char2) { p--; break; }
- }
- }
- else
- {
- while (p < end_subject)
- {
- if (*p++ == req_char) { p--; break; }
- }
- }
-
- /* If we can't find the required character, break the matching loop,
- forcing a match failure. */
-
- if (p >= end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If we have found the required character, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
-
- req_char_ptr = p;
- }
- }
- }
-
-#ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */
- printf(">>>> Match against: ");
- pchars(start_match, end_subject - start_match, TRUE, md);
- printf("\n");
-#endif
-
- /* OK, we can now run the match. If "hitend" is set afterwards, remember the
- first starting point for which a partial match was found. */
-
- md->start_match_ptr = start_match;
- md->start_used_ptr = start_match;
- md->match_call_count = 0;
- md->match_function_type = 0;
- md->end_offset_top = 0;
- rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
- if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
-
- switch(rc)
- {
- /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
- the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
- entirely. The only way we can do that is to re-do the match at the same
- point, with a flag to force SKIP with an argument to be ignored. Just
- treating this case as NOMATCH does not work because it does not check other
- alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
-
- case MATCH_SKIP_ARG:
- new_start_match = start_match;
- md->ignore_skip_arg = TRUE;
- break;
-
- /* SKIP passes back the next starting point explicitly, but if it is the
- same as the match we have just done, treat it as NOMATCH. */
-
- case MATCH_SKIP:
- if (md->start_match_ptr != start_match)
- {
- new_start_match = md->start_match_ptr;
- break;
- }
- /* Fall through */
-
- /* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
-
- case MATCH_NOMATCH:
- case MATCH_PRUNE:
- case MATCH_THEN:
- md->ignore_skip_arg = FALSE;
- new_start_match = start_match + 1;
-#ifdef SUPPORT_UTF
- if (utf)
- ACROSSCHAR(new_start_match < end_subject, *new_start_match,
- new_start_match++);
-#endif
- break;
-
- /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
-
- case MATCH_COMMIT:
- rc = MATCH_NOMATCH;
- goto ENDLOOP;
-
- /* Any other return is either a match, or some kind of error. */
-
- default:
- goto ENDLOOP;
- }
-
- /* Control reaches here for the various types of "no match at this point"
- result. Reset the code to MATCH_NOMATCH for subsequent checking. */
-
- rc = MATCH_NOMATCH;
-
- /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
- newline in the subject (though it may continue over the newline). Therefore,
- if we have just failed to match, starting at a newline, do not continue. */
-
- if (firstline && IS_NEWLINE(start_match)) break;
-
- /* Advance to new matching position */
-
- start_match = new_start_match;
-
- /* Break the loop if the pattern is anchored or if we have passed the end of
- the subject. */
-
- if (anchored || start_match > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. In
- normal matching start_match will aways be greater than the first position at
- this stage, but a failed *SKIP can cause a return at the same point, which is
- why the first test exists. */
-
- if (start_match > (PCRE_PUCHAR)subject + start_offset &&
- start_match[-1] == CHAR_CR &&
- start_match < end_subject &&
- *start_match == CHAR_NL &&
- (re->flags & PCRE_HASCRORLF) == 0 &&
- (md->nltype == NLTYPE_ANY ||
- md->nltype == NLTYPE_ANYCRLF ||
- md->nllen == 2))
- start_match++;
-
- md->mark = NULL; /* Reset for start of next match attempt */
- } /* End of for(;;) "bumpalong" loop */
-
-/* ==========================================================================*/
-
-/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
-conditions is true:
-
-(1) The pattern is anchored or the match was failed by (*COMMIT);
-
-(2) We are past the end of the subject;
-
-(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
- this option requests that a match occur at or before the first newline in
- the subject.
-
-When we have a match and the offset vector is big enough to deal with any
-backreferences, captured substring offsets will already be set up. In the case
-where we had to get some local store to hold offsets for backreference
-processing, copy those that we can. In this case there need not be overflow if
-certain parts of the pattern were not used, even though there are more
-capturing parentheses than vector slots. */
-
-ENDLOOP:
-
-if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
- {
- if (using_temporary_offsets)
- {
- if (arg_offset_max >= 4)
- {
- memcpy(offsets + 2, md->offset_vector + 2,
- (arg_offset_max - 2) * sizeof(int));
- DPRINTF(("Copied offsets from temporary memory\n"));
- }
- if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
- DPRINTF(("Freeing temporary memory\n"));
- (PUBL(free))(md->offset_vector);
- }
-
- /* Set the return code to the number of captured strings, or 0 if there were
- too many to fit into the vector. */
-
- rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?
- 0 : md->end_offset_top/2;
-
- /* If there is space in the offset vector, set any unused pairs at the end of
- the pattern to -1 for backwards compatibility. It is documented that this
- happens. In earlier versions, the whole set of potential capturing offsets
- was set to -1 each time round the loop, but this is handled differently now.
- "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only
- those at the end that need unsetting here. We can't just unset them all at
- the start of the whole thing because they may get set in one branch that is
- not the final matching branch. */
-
- if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL)
- {
- int *iptr, *iend;
- int resetcount = 2 + re->top_bracket * 2;
- if (resetcount > offsetcount) resetcount = offsetcount;
- iptr = offsets + md->end_offset_top;
- iend = offsets + resetcount;
- while (iptr < iend) *iptr++ = -1;
- }
-
- /* If there is space, set up the whole thing as substring 0. The value of
- md->start_match_ptr might be modified if \K was encountered on the success
- matching path. */
-
- if (offsetcount < 2) rc = 0; else
- {
- offsets[0] = (int)(md->start_match_ptr - md->start_subject);
- offsets[1] = (int)(md->end_match_ptr - md->start_subject);
- }
-
- /* Return MARK data if requested */
-
- if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (pcre_uchar *)md->mark;
- DPRINTF((">>>> returning %d\n", rc));
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
- return rc;
- }
-
-/* Control gets here if there has been an error, or if the overall match
-attempt has failed at all permitted starting positions. */
-
-if (using_temporary_offsets)
- {
- DPRINTF(("Freeing temporary memory\n"));
- (PUBL(free))(md->offset_vector);
- }
-
-/* For anything other than nomatch or partial match, just return the code. */
-
-if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
- {
- DPRINTF((">>>> error: returning %d\n", rc));
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
- return rc;
- }
-
-/* Handle partial matches - disable any mark data */
-
-if (start_partial != NULL)
- {
- DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
- md->mark = NULL;
- if (offsetcount > 1)
- {
- offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
- offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
- }
- rc = PCRE_ERROR_PARTIAL;
- }
-
-/* This is the classic nomatch case */
-
-else
- {
- DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
- rc = PCRE_ERROR_NOMATCH;
- }
-
-/* Return the MARK data if it has been requested. */
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
-return rc;
-}
-
-/* End of pcre_exec.c */
diff --git a/glib/pcre/pcre_fullinfo.c b/glib/pcre/pcre_fullinfo.c
deleted file mode 100644
index 2fe785a13..000000000
--- a/glib/pcre/pcre_fullinfo.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_fullinfo(), which returns
-information about a compiled pattern. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return info about compiled pattern *
-*************************************************/
-
-/* This is a newer "info" function which has an extensible interface so
-that additional items can be added compatibly.
-
-Arguments:
- argument_re points to compiled code
- extra_data points extra data, or NULL
- what what information is required
- where where to put the information
-
-Returns: 0 if data returned, negative on error
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
- int what, void *where)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
- int what, void *where)
-#endif
-{
-const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
-const pcre_study_data *study = NULL;
-
-if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-
-/* Check that this pattern was compiled in the correct bit mode */
-
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-switch (what)
- {
- case PCRE_INFO_OPTIONS:
- *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
- break;
-
- case PCRE_INFO_SIZE:
- *((size_t *)where) = re->size;
- break;
-
- case PCRE_INFO_STUDYSIZE:
- *((size_t *)where) = (study == NULL)? 0 : study->size;
- break;
-
- case PCRE_INFO_JITSIZE:
-#ifdef SUPPORT_JIT
- *((size_t *)where) =
- (extra_data != NULL &&
- (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra_data->executable_jit != NULL)?
- PRIV(jit_get_size)(extra_data->executable_jit) : 0;
-#else
- *((size_t *)where) = 0;
-#endif
- break;
-
- case PCRE_INFO_CAPTURECOUNT:
- *((int *)where) = re->top_bracket;
- break;
-
- case PCRE_INFO_BACKREFMAX:
- *((int *)where) = re->top_backref;
- break;
-
- case PCRE_INFO_FIRSTBYTE:
- *((int *)where) =
- ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char :
- ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
- break;
-
- /* Make sure we pass back the pointer to the bit vector in the external
- block, not the internal copy (with flipped integer fields). */
-
- case PCRE_INFO_FIRSTTABLE:
- *((const pcre_uint8 **)where) =
- (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
- ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
- break;
-
- case PCRE_INFO_MINLENGTH:
- *((int *)where) =
- (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
- (int)(study->minlength) : -1;
- break;
-
- case PCRE_INFO_JIT:
- *((int *)where) = extra_data != NULL &&
- (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra_data->executable_jit != NULL;
- break;
-
- case PCRE_INFO_LASTLITERAL:
- *((int *)where) =
- ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1;
- break;
-
- case PCRE_INFO_NAMEENTRYSIZE:
- *((int *)where) = re->name_entry_size;
- break;
-
- case PCRE_INFO_NAMECOUNT:
- *((int *)where) = re->name_count;
- break;
-
- case PCRE_INFO_NAMETABLE:
- *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
- break;
-
- case PCRE_INFO_DEFAULT_TABLES:
- *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
- break;
-
- /* From release 8.00 this will always return TRUE because NOPARTIAL is
- no longer ever set (the restrictions have been removed). */
-
- case PCRE_INFO_OKPARTIAL:
- *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
- break;
-
- case PCRE_INFO_JCHANGED:
- *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
- break;
-
- case PCRE_INFO_HASCRORLF:
- *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
- break;
-
- case PCRE_INFO_MAXLOOKBEHIND:
- *((int *)where) = re->max_lookbehind;
- break;
-
- default: return PCRE_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-/* End of pcre_fullinfo.c */
diff --git a/glib/pcre/pcre_get.c b/glib/pcre/pcre_get.c
deleted file mode 100644
index 61147efe8..000000000
--- a/glib/pcre/pcre_get.c
+++ /dev/null
@@ -1,585 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains some convenience functions for extracting substrings
-from the subject string after a regex match has succeeded. The original idea
-for these functions came from Scott Wimer. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Find number for named string *
-*************************************************/
-
-/* This function is used by the get_first_set() function below, as well
-as being generally available. It assumes that names are unique.
-
-Arguments:
- code the compiled regex
- stringname the name whose number is required
-
-Returns: the number of the named parentheses, or a negative number
- (PCRE_ERROR_NOSUBSTRING) if not found
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_stringnumber(const pcre *code, const char *stringname)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
-#endif
-{
-int rc;
-int entrysize;
-int top, bot;
-pcre_uchar *nametable;
-
-#ifdef COMPILE_PCRE8
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-#endif
-#ifdef COMPILE_PCRE16
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-#endif
-
-bot = 0;
-while (top > bot)
- {
- int mid = (top + bot) / 2;
- pcre_uchar *entry = nametable + entrysize*mid;
- int c = STRCMP_UC_UC((pcre_uchar *)stringname,
- (pcre_uchar *)(entry + IMM2_SIZE));
- if (c == 0) return GET2(entry, 0);
- if (c > 0) bot = mid + 1; else top = mid;
- }
-
-return PCRE_ERROR_NOSUBSTRING;
-}
-
-
-
-/*************************************************
-* Find (multiple) entries for named string *
-*************************************************/
-
-/* This is used by the get_first_set() function below, as well as being
-generally available. It is used when duplicated names are permitted.
-
-Arguments:
- code the compiled regex
- stringname the name whose entries required
- firstptr where to put the pointer to the first entry
- lastptr where to put the pointer to the last entry
-
-Returns: the length of each entry, or a negative number
- (PCRE_ERROR_NOSUBSTRING) if not found
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_stringtable_entries(const pcre *code, const char *stringname,
- char **firstptr, char **lastptr)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
- PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
-#endif
-{
-int rc;
-int entrysize;
-int top, bot;
-pcre_uchar *nametable, *lastentry;
-
-#ifdef COMPILE_PCRE8
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-#endif
-#ifdef COMPILE_PCRE16
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-#endif
-
-lastentry = nametable + entrysize * (top - 1);
-bot = 0;
-while (top > bot)
- {
- int mid = (top + bot) / 2;
- pcre_uchar *entry = nametable + entrysize*mid;
- int c = STRCMP_UC_UC((pcre_uchar *)stringname,
- (pcre_uchar *)(entry + IMM2_SIZE));
- if (c == 0)
- {
- pcre_uchar *first = entry;
- pcre_uchar *last = entry;
- while (first > nametable)
- {
- if (STRCMP_UC_UC((pcre_uchar *)stringname,
- (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
- first -= entrysize;
- }
- while (last < lastentry)
- {
- if (STRCMP_UC_UC((pcre_uchar *)stringname,
- (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
- last += entrysize;
- }
-#ifdef COMPILE_PCRE8
- *firstptr = (char *)first;
- *lastptr = (char *)last;
-#else
- *firstptr = (PCRE_UCHAR16 *)first;
- *lastptr = (PCRE_UCHAR16 *)last;
-#endif
- return entrysize;
- }
- if (c > 0) bot = mid + 1; else top = mid;
- }
-
-return PCRE_ERROR_NOSUBSTRING;
-}
-
-
-
-/*************************************************
-* Find first set of multiple named strings *
-*************************************************/
-
-/* This function allows for duplicate names in the table of named substrings.
-It returns the number of the first one that was set in a pattern match.
-
-Arguments:
- code the compiled regex
- stringname the name of the capturing substring
- ovector the vector of matched substrings
-
-Returns: the number of the first that is set,
- or the number of the last one if none are set,
- or a negative number on error
-*/
-
-#ifdef COMPILE_PCRE8
-static int
-get_first_set(const pcre *code, const char *stringname, int *ovector)
-#else
-static int
-get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector)
-#endif
-{
-const REAL_PCRE *re = (const REAL_PCRE *)code;
-int entrysize;
-pcre_uchar *entry;
-#ifdef COMPILE_PCRE8
-char *first, *last;
-#else
-PCRE_UCHAR16 *first, *last;
-#endif
-
-#ifdef COMPILE_PCRE8
-if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
- return pcre_get_stringnumber(code, stringname);
-entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
-#else
-if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
- return pcre16_get_stringnumber(code, stringname);
-entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
-#endif
-if (entrysize <= 0) return entrysize;
-for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
- {
- int n = GET2(entry, 0);
- if (ovector[n*2] >= 0) return n;
- }
-return GET2(entry, 0);
-}
-
-
-
-
-/*************************************************
-* Copy captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer.
-Note that we use memcpy() rather than strncpy() in case there are binary zeros
-in the string.
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringnumber the number of the required substring
- buffer where to put the substring
- size the size of the buffer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) buffer too small
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_copy_substring(const char *subject, int *ovector, int stringcount,
- int stringnumber, char *buffer, int size)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
- int stringnumber, PCRE_UCHAR16 *buffer, int size)
-#endif
-{
-int yield;
-if (stringnumber < 0 || stringnumber >= stringcount)
- return PCRE_ERROR_NOSUBSTRING;
-stringnumber *= 2;
-yield = ovector[stringnumber+1] - ovector[stringnumber];
-if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
-memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
-buffer[yield] = 0;
-return yield;
-}
-
-
-
-/*************************************************
-* Copy named captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer,
-identifying it by name. If the regex permits duplicate names, the first
-substring that is set is chosen.
-
-Arguments:
- code the compiled regex
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringname the name of the required substring
- buffer where to put the substring
- size the size of the buffer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) buffer too small
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_copy_named_substring(const pcre *code, const char *subject,
- int *ovector, int stringcount, const char *stringname,
- char *buffer, int size)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
- int *ovector, int stringcount, PCRE_SPTR16 stringname,
- PCRE_UCHAR16 *buffer, int size)
-#endif
-{
-int n = get_first_set(code, stringname, ovector);
-if (n <= 0) return n;
-#ifdef COMPILE_PCRE8
-return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
-#else
-return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
-#endif
-}
-
-
-
-/*************************************************
-* Copy all captured strings to new store *
-*************************************************/
-
-/* This function gets one chunk of store and builds a list of pointers and all
-of the captured substrings in it. A NULL pointer is put on the end of the list.
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- listptr set to point to the list of pointers
-
-Returns: if successful: 0
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) failed to get store
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
- const char ***listptr)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
- PCRE_SPTR16 **listptr)
-#endif
-{
-int i;
-int size = sizeof(pcre_uchar *);
-int double_count = stringcount * 2;
-pcre_uchar **stringlist;
-pcre_uchar *p;
-
-for (i = 0; i < double_count; i += 2)
- size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1);
-
-stringlist = (pcre_uchar **)(PUBL(malloc))(size);
-if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
-
-#ifdef COMPILE_PCRE8
-*listptr = (const char **)stringlist;
-#else
-*listptr = (PCRE_SPTR16 *)stringlist;
-#endif
-p = (pcre_uchar *)(stringlist + stringcount + 1);
-
-for (i = 0; i < double_count; i += 2)
- {
- int len = ovector[i+1] - ovector[i];
- memcpy(p, subject + ovector[i], IN_UCHARS(len));
- *stringlist++ = p;
- p += len;
- *p++ = 0;
- }
-
-*stringlist = NULL;
-return 0;
-}
-
-
-
-/*************************************************
-* Free store obtained by get_substring_list *
-*************************************************/
-
-/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (PUBL(free))()
-directly.
-
-Argument: the result of a previous pcre_get_substring_list()
-Returns: nothing
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
-pcre_free_substring_list(const char **pointer)
-#else
-PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
-pcre16_free_substring_list(PCRE_SPTR16 *pointer)
-#endif
-{
-(PUBL(free))((void *)pointer);
-}
-
-
-
-/*************************************************
-* Copy captured string to new store *
-*************************************************/
-
-/* This function copies a single captured substring into a piece of new
-store
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringnumber the number of the required substring
- stringptr where to put a pointer to the substring
-
-Returns: if successful:
- the length of the string, not including the zero that
- is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) failed to get store
- PCRE_ERROR_NOSUBSTRING (-7) substring not present
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_substring(const char *subject, int *ovector, int stringcount,
- int stringnumber, const char **stringptr)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
- int stringnumber, PCRE_SPTR16 *stringptr)
-#endif
-{
-int yield;
-pcre_uchar *substring;
-if (stringnumber < 0 || stringnumber >= stringcount)
- return PCRE_ERROR_NOSUBSTRING;
-stringnumber *= 2;
-yield = ovector[stringnumber+1] - ovector[stringnumber];
-substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
-if (substring == NULL) return PCRE_ERROR_NOMEMORY;
-memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
-substring[yield] = 0;
-#ifdef COMPILE_PCRE8
-*stringptr = (const char *)substring;
-#else
-*stringptr = (PCRE_SPTR16)substring;
-#endif
-return yield;
-}
-
-
-
-/*************************************************
-* Copy named captured string to new store *
-*************************************************/
-
-/* This function copies a single captured substring, identified by name, into
-new store. If the regex permits duplicate names, the first substring that is
-set is chosen.
-
-Arguments:
- code the compiled regex
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringname the name of the required substring
- stringptr where to put the pointer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) couldn't get memory
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_named_substring(const pcre *code, const char *subject,
- int *ovector, int stringcount, const char *stringname,
- const char **stringptr)
-#else
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
- int *ovector, int stringcount, PCRE_SPTR16 stringname,
- PCRE_SPTR16 *stringptr)
-#endif
-{
-int n = get_first_set(code, stringname, ovector);
-if (n <= 0) return n;
-#ifdef COMPILE_PCRE8
-return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
-#else
-return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
-#endif
-}
-
-
-
-
-/*************************************************
-* Free store obtained by get_substring *
-*************************************************/
-
-/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (PUBL(free))()
-directly.
-
-Argument: the result of a previous pcre_get_substring()
-Returns: nothing
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
-pcre_free_substring(const char *pointer)
-#else
-PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
-pcre16_free_substring(PCRE_SPTR16 pointer)
-#endif
-{
-(PUBL(free))((void *)pointer);
-}
-
-/* End of pcre_get.c */
diff --git a/glib/pcre/pcre_globals.c b/glib/pcre/pcre_globals.c
deleted file mode 100644
index 383ec7311..000000000
--- a/glib/pcre/pcre_globals.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains global variables that are exported by the PCRE library.
-PCRE is thread-clean and doesn't use any global variables in the normal sense.
-However, it calls memory allocation and freeing functions via the four
-indirections below, and it can optionally do callouts, using the fifth
-indirection. These values can be changed by the caller, but are shared between
-all threads.
-
-For MS Visual Studio and Symbian OS, there are problems in initializing these
-variables to non-local functions. In these cases, therefore, an indirection via
-a local function is used.
-
-Also, when compiling for Virtual Pascal, things are done differently, and
-global variables are not used. */
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-#ifdef GLIB_COMPILATION
-#include "gmem.h"
-#else
-#include <glib.h>
-#endif /* GLIB_COMPILATION */
-
-#if defined _MSC_VER || defined __SYMBIAN32__
-static void* LocalPcreMalloc(size_t aSize)
- {
- return malloc(aSize);
- }
-static void LocalPcreFree(void* aPtr)
- {
- free(aPtr);
- }
-PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-
-#elif !defined VPCOMPAT
-PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = g_try_malloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = g_free;
-PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = g_try_malloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = g_free;
-PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-#endif
-
-/* End of pcre_globals.c */
diff --git a/glib/pcre/pcre_internal.h b/glib/pcre/pcre_internal.h
deleted file mode 100644
index 9918e71a4..000000000
--- a/glib/pcre/pcre_internal.h
+++ /dev/null
@@ -1,2334 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This header contains definitions that are shared between the different
-modules, but which are not relevant to the exported API. This includes some
-functions whose names all begin with "_pcre_" or "_pcre16_" depending on
-the PRIV macro. */
-
-#ifndef PCRE_INTERNAL_H
-#define PCRE_INTERNAL_H
-
-/* Define PCRE_DEBUG to get debugging output on stdout. */
-
-#if 0
-#define PCRE_DEBUG
-#endif
-
-/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */
-#ifndef COMPILE_PCRE16
-#define COMPILE_PCRE8
-#endif
-
-/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
-"configure" script ensures this, but not everybody uses "configure". */
-
-#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
-#define SUPPORT_UTF 1
-#endif
-
-/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
-reasons with existing code. */
-
-#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
-#define SUPPORT_UTF 1
-#endif
-
-/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
-Until then we define it if SUPPORT_UTF is defined. */
-
-#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
-#define SUPPORT_UTF8 1
-#endif
-
-/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure"
-script prevents both being selected, but not everybody uses "configure". */
-
-#if defined EBCDIC && defined SUPPORT_UTF
-#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported.
-#endif
-
-/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
-inline, and there are *still* stupid compilers about that don't like indented
-pre-processor statements, or at least there were when I first wrote this. After
-all, it had only been about 10 years then...
-
-It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
-be absolutely sure we get our version. */
-
-#undef DPRINTF
-#ifdef PCRE_DEBUG
-#define DPRINTF(p) printf p
-#else
-#define DPRINTF(p) /* Nothing */
-#endif
-
-
-/* Standard C headers plus the external interface definition. The only time
-setjmp and stdarg are used is when NO_RECURSE is set. */
-
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
-which is all that is needed for applications (they just import the symbols). We
-use:
-
- PCRE_EXP_DECL for declarations
- PCRE_EXP_DEFN for definitions of exported functions
- PCRE_EXP_DATA_DEFN for definitions of exported variables
-
-The reason for the two DEFN macros is that in non-Windows environments, one
-does not want to have "extern" before variable definitions because it leads to
-compiler warnings. So we distinguish between functions and variables. In
-Windows, the two should always be the same.
-
-The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
-which is an application, but needs to import this file in order to "peek" at
-internals, can #include pcre.h first to get an application's-eye view.
-
-In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
-special-purpose environments) might want to stick other stuff in front of
-exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
-PCRE_EXP_DATA_DEFN only if they are not already set. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE_STATIC
-# define PCRE_EXP_DECL extern __declspec(dllexport)
-# define PCRE_EXP_DEFN __declspec(dllexport)
-# define PCRE_EXP_DATA_DEFN __declspec(dllexport)
-# else
-# define PCRE_EXP_DECL extern
-# define PCRE_EXP_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# else
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-# ifndef PCRE_EXP_DEFN
-# define PCRE_EXP_DEFN PCRE_EXP_DECL
-# endif
-# ifndef PCRE_EXP_DATA_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# endif
-#endif
-
-/* When compiling with the MSVC compiler, it is sometimes necessary to include
-a "calling convention" before exported function names. (This is secondhand
-information; I know nothing about MSVC myself). For example, something like
-
- void __cdecl function(....)
-
-might be needed. In order so make this easy, all the exported functions have
-PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
-set, we ensure here that it has no effect. */
-
-#ifndef PCRE_CALL_CONVENTION
-#define PCRE_CALL_CONVENTION
-#endif
-
-/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
-cannot determine these outside the compilation (e.g. by running a program as
-part of "configure") because PCRE is often cross-compiled for use on other
-systems. Instead we make use of the maximum sizes that are available at
-preprocessor time in standard C environments. */
-
-typedef unsigned char pcre_uint8;
-
-#if USHRT_MAX == 65535
- typedef unsigned short pcre_uint16;
- typedef short pcre_int16;
-#elif UINT_MAX == 65535
- typedef unsigned int pcre_uint16;
- typedef int pcre_int16;
-#else
- #error Cannot determine a type for 16-bit unsigned integers
-#endif
-
-#if UINT_MAX == 4294967295
- typedef unsigned int pcre_uint32;
- typedef int pcre_int32;
-#elif ULONG_MAX == 4294967295
- typedef unsigned long int pcre_uint32;
- typedef long int pcre_int32;
-#else
- #error Cannot determine a type for 32-bit unsigned integers
-#endif
-
-/* When checking for integer overflow in pcre_compile(), we need to handle
-large integers. If a 64-bit integer type is available, we can use that.
-Otherwise we have to cast to double, which of course requires floating point
-arithmetic. Handle this by defining a macro for the appropriate type. If
-stdint.h is available, include it; it may define INT64_MAX. Systems that do not
-have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
-by "configure". */
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#if defined INT64_MAX || defined int64_t
-#define INT64_OR_DOUBLE int64_t
-#else
-#define INT64_OR_DOUBLE double
-#endif
-
-/* All character handling must be done as unsigned characters. Otherwise there
-are problems with top-bit-set characters and functions such as isspace().
-However, we leave the interface to the outside world as char * or short *,
-because that should make things easier for callers. This character type is
-called pcre_uchar.
-
-The IN_UCHARS macro multiply its argument with the byte size of the current
-pcre_uchar type. Useful for memcpy and such operations, whose require the
-byte size of their input/output buffers.
-
-The MAX_255 macro checks whether its pcre_uchar input is less than 256.
-
-The TABLE_GET macro is designed for accessing elements of tables whose contain
-exactly 256 items. When the character is able to contain more than 256
-items, some check is needed before accessing these tables.
-*/
-
-#ifdef COMPILE_PCRE8
-
-typedef unsigned char pcre_uchar;
-#define IN_UCHARS(x) (x)
-#define MAX_255(c) 1
-#define TABLE_GET(c, table, default) ((table)[c])
-
-#else
-
-#ifdef COMPILE_PCRE16
-#if USHRT_MAX != 65535
-/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
-pcre.h(.in) and disable (comment out) this message. */
-#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
-#endif
-
-typedef pcre_uint16 pcre_uchar;
-#define IN_UCHARS(x) ((x) << 1)
-#define MAX_255(c) ((c) <= 255u)
-#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE16 */
-
-#endif /* COMPILE_PCRE8 */
-
-/* This is an unsigned int value that no character can ever have. UTF-8
-characters only go up to 0x7fffffff (though Unicode doesn't go beyond
-0x0010ffff). */
-
-#define NOTACHAR 0xffffffff
-
-/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
-"any" and "anycrlf" at present). The following macros are used to package up
-testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
-modules to indicate in which datablock the parameters exist, and what the
-start/end of string field names are. */
-
-#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
-#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
-#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
-
-/* This macro checks for a newline at the given position */
-
-#define IS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) < NLBLOCK->PSEND && \
- PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
- (p)[0] == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* This macro checks for a newline immediately preceding the given position */
-
-#define WAS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) > NLBLOCK->PSSTART && \
- PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
- (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
-with a custom type. This makes it possible, for example, to allow pcre_exec()
-to process subject strings that are discontinuous by using a smart pointer
-class. It must always be possible to inspect all of the subject string in
-pcre_exec() because of the way it backtracks. Two macros are required in the
-normal case, for sign-unspecified and unsigned char pointers. The former is
-used for the external interface and appears in pcre.h, which is why its name
-must begin with PCRE_. */
-
-#ifdef CUSTOM_SUBJECT_PTR
-#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
-#else
-#define PCRE_PUCHAR const pcre_uchar *
-#endif
-
-/* Include the public PCRE header and the definitions of UCP character property
-values. */
-
-#include "pcre.h"
-#include "ucp.h"
-
-/* When compiling for use with the Virtual Pascal compiler, these functions
-need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
-option on the command line. */
-
-#ifdef VPCOMPAT
-#define strlen(s) _strlen(s)
-#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
-#define memcmp(s,c,n) _memcmp(s,c,n)
-#define memcpy(d,s,n) _memcpy(d,s,n)
-#define memmove(d,s,n) _memmove(d,s,n)
-#define memset(s,c,n) _memset(s,c,n)
-#else /* VPCOMPAT */
-
-/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
-define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
-is set. Otherwise, include an emulating function for those systems that have
-neither (there some non-Unix environments where this is the case). */
-
-#ifndef HAVE_MEMMOVE
-#undef memmove /* some systems may have a macro */
-#ifdef HAVE_BCOPY
-#define memmove(a, b, c) bcopy(b, a, c)
-#else /* HAVE_BCOPY */
-static void *
-pcre_memmove(void *d, const void *s, size_t n)
-{
-size_t i;
-unsigned char *dest = (unsigned char *)d;
-const unsigned char *src = (const unsigned char *)s;
-if (dest > src)
- {
- dest += n;
- src += n;
- for (i = 0; i < n; ++i) *(--dest) = *(--src);
- return (void *)dest;
- }
-else
- {
- for (i = 0; i < n; ++i) *dest++ = *src++;
- return (void *)(dest - n);
- }
-}
-#define memmove(a, b, c) pcre_memmove(a, b, c)
-#endif /* not HAVE_BCOPY */
-#endif /* not HAVE_MEMMOVE */
-#endif /* not VPCOMPAT */
-
-
-/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
-in big-endian order) by default. These are used, for example, to link from the
-start of a subpattern to its alternatives and its end. The use of 2 bytes per
-offset limits the size of the compiled regex to around 64K, which is big enough
-for almost everybody. However, I received a request for an even bigger limit.
-For this reason, and also to make the code easier to maintain, the storing and
-loading of offsets from the byte string is now handled by the macros that are
-defined here.
-
-The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
-the config.h file, but can be overridden by using -D on the command line. This
-is automated on Unix systems via the "configure" command. */
-
-#ifdef COMPILE_PCRE8
-
-#if LINK_SIZE == 2
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 8), \
- (a[(n)+1] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 8) | (a)[(n)+1])
-
-#define MAX_PATTERN_SIZE (1 << 16)
-
-
-#elif LINK_SIZE == 3
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 16), \
- (a[(n)+1] = (d) >> 8), \
- (a[(n)+2] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
-
-#define MAX_PATTERN_SIZE (1 << 24)
-
-
-#elif LINK_SIZE == 4
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 24), \
- (a[(n)+1] = (d) >> 16), \
- (a[(n)+2] = (d) >> 8), \
- (a[(n)+3] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
-
-/* Keep it positive */
-#define MAX_PATTERN_SIZE (1 << 30)
-
-#else
-#error LINK_SIZE must be either 2, 3, or 4
-#endif
-
-#else /* COMPILE_PCRE8 */
-
-#ifdef COMPILE_PCRE16
-
-#if LINK_SIZE == 2
-
-#undef LINK_SIZE
-#define LINK_SIZE 1
-
-#define PUT(a,n,d) \
- (a[n] = (d))
-
-#define GET(a,n) \
- (a[n])
-
-#define MAX_PATTERN_SIZE (1 << 16)
-
-#elif LINK_SIZE == 3 || LINK_SIZE == 4
-
-#undef LINK_SIZE
-#define LINK_SIZE 2
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 16), \
- (a[(n)+1] = (d) & 65535)
-
-#define GET(a,n) \
- (((a)[n] << 16) | (a)[(n)+1])
-
-/* Keep it positive */
-#define MAX_PATTERN_SIZE (1 << 30)
-
-#else
-#error LINK_SIZE must be either 2, 3, or 4
-#endif
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE16 */
-
-#endif /* COMPILE_PCRE8 */
-
-/* Convenience macro defined in terms of the others */
-
-#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
-
-
-/* PCRE uses some other 2-byte quantities that do not change when the size of
-offsets changes. There are used for repeat counts and for other things such as
-capturing parenthesis numbers in back references. */
-
-#ifdef COMPILE_PCRE8
-
-#define IMM2_SIZE 2
-
-#define PUT2(a,n,d) \
- a[n] = (d) >> 8; \
- a[(n)+1] = (d) & 255
-
-#define GET2(a,n) \
- (((a)[n] << 8) | (a)[(n)+1])
-
-#else /* COMPILE_PCRE8 */
-
-#ifdef COMPILE_PCRE16
-
-#define IMM2_SIZE 1
-
-#define PUT2(a,n,d) \
- a[n] = d
-
-#define GET2(a,n) \
- a[n]
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE16 */
-
-#endif /* COMPILE_PCRE8 */
-
-#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
-
-/* The maximum length of a MARK name is currently one data unit; it may be
-changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */
-
-#define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1)
-
-/* When UTF encoding is being used, a character is no longer just a single
-character. The macros for character handling generate simple sequences when
-used in character-mode, and more complicated ones for UTF characters.
-GETCHARLENTEST and other macros are not used when UTF is not supported,
-so they are not defined. To make sure they can never even appear when
-UTF support is omitted, we don't even define them. */
-
-#ifndef SUPPORT_UTF
-
-/* #define MAX_VALUE_FOR_SINGLE_CHAR */
-/* #define HAS_EXTRALEN(c) */
-/* #define GET_EXTRALEN(c) */
-/* #define NOT_FIRSTCHAR(c) */
-#define GETCHAR(c, eptr) c = *eptr;
-#define GETCHARTEST(c, eptr) c = *eptr;
-#define GETCHARINC(c, eptr) c = *eptr++;
-#define GETCHARINCTEST(c, eptr) c = *eptr++;
-#define GETCHARLEN(c, eptr, len) c = *eptr;
-/* #define GETCHARLENTEST(c, eptr, len) */
-/* #define BACKCHAR(eptr) */
-/* #define FORWARDCHAR(eptr) */
-/* #define ACROSSCHAR(condition, eptr, action) */
-
-#else /* SUPPORT_UTF */
-
-#ifdef COMPILE_PCRE8
-
-/* These macros were originally written in the form of loops that used data
-from the tables whose names start with PRIV(utf8_table). They were rewritten by
-a user so as not to use loops, because in some environments this gives a
-significant performance advantage, and it seems never to do any harm. */
-
-/* Tells the biggest code point which can be encoded as a single character. */
-
-#define MAX_VALUE_FOR_SINGLE_CHAR 127
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) ((c) >= 0xc0)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])
-
-/* Returns TRUE, if the given character is not the first character
-of a UTF sequence. */
-
-#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer. */
-
-#define GETUTF8(c, eptr) \
- { \
- if ((c & 0x20) == 0) \
- c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
- else if ((c & 0x10) == 0) \
- c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- else if ((c & 0x08) == 0) \
- c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
- ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
- else if ((c & 0x04) == 0) \
- c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
- ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
- (eptr[4] & 0x3f); \
- else \
- c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
- ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
- ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
- }
-
-/* Get the next UTF-8 character, not advancing the pointer. This is called when
-we know we are in UTF-8 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if (c >= 0xc0) GETUTF8(c, eptr);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && c >= 0xc0) GETUTF8(c, eptr);
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
-the pointer. */
-
-#define GETUTF8INC(c, eptr) \
- { \
- if ((c & 0x20) == 0) \
- c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \
- else if ((c & 0x10) == 0) \
- { \
- c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \
- eptr += 2; \
- } \
- else if ((c & 0x08) == 0) \
- { \
- c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \
- ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- eptr += 3; \
- } \
- else if ((c & 0x04) == 0) \
- { \
- c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \
- ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \
- (eptr[3] & 0x3f); \
- eptr += 4; \
- } \
- else \
- { \
- c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \
- ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \
- ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \
- eptr += 5; \
- } \
- }
-
-/* Get the next UTF-8 character, advancing the pointer. This is called when we
-know we are in UTF-8 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if (c >= 0xc0) GETUTF8INC(c, eptr);
-
-/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-8 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && c >= 0xc0) GETUTF8INC(c, eptr);
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF8LEN(c, eptr, len) \
- { \
- if ((c & 0x20) == 0) \
- { \
- c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
- len++; \
- } \
- else if ((c & 0x10) == 0) \
- { \
- c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- len += 2; \
- } \
- else if ((c & 0x08) == 0) \
- {\
- c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
- ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
- len += 3; \
- } \
- else if ((c & 0x04) == 0) \
- { \
- c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
- ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
- (eptr[4] & 0x3f); \
- len += 4; \
- } \
- else \
- {\
- c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
- ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
- ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
- len += 5; \
- } \
- }
-
-/* Get the next UTF-8 character, not advancing the pointer, incrementing length
-if there are extra bytes. This is called when we know we are in UTF-8 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if (c >= 0xc0) GETUTF8LEN(c, eptr, len);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
-pointer, incrementing length if there are extra bytes. This is called when we
-do not know if we are in UTF-8 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-8 mode - we don't put a test within the macro
-because almost all calls are already within a block of UTF-8 only code. */
-
-#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- while((condition) && ((eptr) & 0xc0) == 0x80) action
-
-#else /* COMPILE_PCRE8 */
-
-#ifdef COMPILE_PCRE16
-
-/* Tells the biggest code point which can be encoded as a single character. */
-
-#define MAX_VALUE_FOR_SINGLE_CHAR 65535
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) 1
-
-/* Returns TRUE, if the given character is not the first character
-of a UTF sequence. */
-
-#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer. */
-
-#define GETUTF16(c, eptr) \
- { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }
-
-/* Get the next UTF-16 character, not advancing the pointer. This is called when
-we know we are in UTF-16 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
-
-/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
-the pointer. */
-
-#define GETUTF16INC(c, eptr) \
- { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }
-
-/* Get the next UTF-16 character, advancing the pointer. This is called when we
-know we are in UTF-16 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
-
-/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-16 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF16LEN(c, eptr, len) \
- { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }
-
-/* Get the next UTF-16 character, not advancing the pointer, incrementing
-length if there is a low surrogate. This is called when we know we are in
-UTF-16 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
-
-/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
-pointer, incrementing length if there is a low surrogate. This is called when
-we do not know if we are in UTF-16 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-16 mode - we don't put a test within the
-macro because almost all calls are already within a block of UTF-16 only
-code. */
-
-#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action
-
-#endif
-
-#endif /* COMPILE_PCRE8 */
-
-#endif /* SUPPORT_UTF */
-
-
-/* In case there is no definition of offsetof() provided - though any proper
-Standard C system should have one. */
-
-#ifndef offsetof
-#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
-#endif
-
-
-/* Private flags containing information about the compiled regex. They used to
-live at the top end of the options word, but that got almost full, so now they
-are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as
-the restrictions on partial matching have been lifted. It remains for backwards
-compatibility. */
-
-#ifdef COMPILE_PCRE8
-#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */
-#endif
-#ifdef COMPILE_PCRE16
-#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */
-#endif
-#define PCRE_FIRSTSET 0x0010 /* first_char is set */
-#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */
-#define PCRE_REQCHSET 0x0040 /* req_byte is set */
-#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */
-#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */
-#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */
-#define PCRE_JCHANGED 0x0400 /* j option used in regex */
-#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */
-#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */
-
-/* Flags for the "extra" block produced by pcre_study(). */
-
-#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */
-#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */
-
-/* Masks for identifying the public options that are permitted at compile
-time, run time, or study time, respectively. */
-
-#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
- PCRE_NEWLINE_ANYCRLF)
-
-#define PUBLIC_COMPILE_OPTIONS \
- (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
- PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
- PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
- PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE)
-
-#define PUBLIC_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
- PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
- PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)
-
-#define PUBLIC_DFA_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
- PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
- PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_NO_START_OPTIMIZE)
-
-#define PUBLIC_STUDY_OPTIONS \
- (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \
- PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)
-
-/* Magic number to provide a small check against being handed junk. */
-
-#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
-
-/* This variable is used to detect a loaded regular expression
-in different endianness. */
-
-#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */
-
-/* Negative values for the firstchar and reqchar variables */
-
-#define REQ_UNSET (-2)
-#define REQ_NONE (-1)
-
-/* The maximum remaining length of subject we are prepared to search for a
-req_byte match. */
-
-#define REQ_BYTE_MAX 1000
-
-/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
-environments where these macros are defined elsewhere. Unfortunately, there
-is no way to do the same for the typedef. */
-
-typedef int BOOL;
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
-/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
-character constants like '*' because the compiler would emit their EBCDIC code,
-which is different from their ASCII/UTF-8 code. Instead we define macros for
-the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
-is enabled. When UTF-8 support is not enabled, the definitions use character
-literals. Both character and string versions of each character are needed, and
-there are some longer strings as well.
-
-This means that, on EBCDIC platforms, the PCRE library can handle either
-EBCDIC, or UTF-8, but not both. To support both in the same compiled library
-would need different lookups depending on whether PCRE_UTF8 was set or not.
-This would make it impossible to use characters in switch/case statements,
-which would reduce performance. For a theoretical use (which nobody has asked
-for) in a minority area (EBCDIC platforms), this is not sensible. Any
-application that did need both could compile two versions of the library, using
-macros to give the functions distinct names. */
-
-#ifndef SUPPORT_UTF
-
-/* UTF-8 support is not enabled; use the platform-dependent character literals
-so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */
-
-#define CHAR_HT '\t'
-#define CHAR_VT '\v'
-#define CHAR_FF '\f'
-#define CHAR_CR '\r'
-#define CHAR_NL '\n'
-#define CHAR_BS '\b'
-#define CHAR_BEL '\a'
-#ifdef EBCDIC
-#define CHAR_ESC '\047'
-#define CHAR_DEL '\007'
-#else
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-#endif
-
-#define CHAR_SPACE ' '
-#define CHAR_EXCLAMATION_MARK '!'
-#define CHAR_QUOTATION_MARK '"'
-#define CHAR_NUMBER_SIGN '#'
-#define CHAR_DOLLAR_SIGN '$'
-#define CHAR_PERCENT_SIGN '%'
-#define CHAR_AMPERSAND '&'
-#define CHAR_APOSTROPHE '\''
-#define CHAR_LEFT_PARENTHESIS '('
-#define CHAR_RIGHT_PARENTHESIS ')'
-#define CHAR_ASTERISK '*'
-#define CHAR_PLUS '+'
-#define CHAR_COMMA ','
-#define CHAR_MINUS '-'
-#define CHAR_DOT '.'
-#define CHAR_SLASH '/'
-#define CHAR_0 '0'
-#define CHAR_1 '1'
-#define CHAR_2 '2'
-#define CHAR_3 '3'
-#define CHAR_4 '4'
-#define CHAR_5 '5'
-#define CHAR_6 '6'
-#define CHAR_7 '7'
-#define CHAR_8 '8'
-#define CHAR_9 '9'
-#define CHAR_COLON ':'
-#define CHAR_SEMICOLON ';'
-#define CHAR_LESS_THAN_SIGN '<'
-#define CHAR_EQUALS_SIGN '='
-#define CHAR_GREATER_THAN_SIGN '>'
-#define CHAR_QUESTION_MARK '?'
-#define CHAR_COMMERCIAL_AT '@'
-#define CHAR_A 'A'
-#define CHAR_B 'B'
-#define CHAR_C 'C'
-#define CHAR_D 'D'
-#define CHAR_E 'E'
-#define CHAR_F 'F'
-#define CHAR_G 'G'
-#define CHAR_H 'H'
-#define CHAR_I 'I'
-#define CHAR_J 'J'
-#define CHAR_K 'K'
-#define CHAR_L 'L'
-#define CHAR_M 'M'
-#define CHAR_N 'N'
-#define CHAR_O 'O'
-#define CHAR_P 'P'
-#define CHAR_Q 'Q'
-#define CHAR_R 'R'
-#define CHAR_S 'S'
-#define CHAR_T 'T'
-#define CHAR_U 'U'
-#define CHAR_V 'V'
-#define CHAR_W 'W'
-#define CHAR_X 'X'
-#define CHAR_Y 'Y'
-#define CHAR_Z 'Z'
-#define CHAR_LEFT_SQUARE_BRACKET '['
-#define CHAR_BACKSLASH '\\'
-#define CHAR_RIGHT_SQUARE_BRACKET ']'
-#define CHAR_CIRCUMFLEX_ACCENT '^'
-#define CHAR_UNDERSCORE '_'
-#define CHAR_GRAVE_ACCENT '`'
-#define CHAR_a 'a'
-#define CHAR_b 'b'
-#define CHAR_c 'c'
-#define CHAR_d 'd'
-#define CHAR_e 'e'
-#define CHAR_f 'f'
-#define CHAR_g 'g'
-#define CHAR_h 'h'
-#define CHAR_i 'i'
-#define CHAR_j 'j'
-#define CHAR_k 'k'
-#define CHAR_l 'l'
-#define CHAR_m 'm'
-#define CHAR_n 'n'
-#define CHAR_o 'o'
-#define CHAR_p 'p'
-#define CHAR_q 'q'
-#define CHAR_r 'r'
-#define CHAR_s 's'
-#define CHAR_t 't'
-#define CHAR_u 'u'
-#define CHAR_v 'v'
-#define CHAR_w 'w'
-#define CHAR_x 'x'
-#define CHAR_y 'y'
-#define CHAR_z 'z'
-#define CHAR_LEFT_CURLY_BRACKET '{'
-#define CHAR_VERTICAL_LINE '|'
-#define CHAR_RIGHT_CURLY_BRACKET '}'
-#define CHAR_TILDE '~'
-
-#define STR_HT "\t"
-#define STR_VT "\v"
-#define STR_FF "\f"
-#define STR_CR "\r"
-#define STR_NL "\n"
-#define STR_BS "\b"
-#define STR_BEL "\a"
-#ifdef EBCDIC
-#define STR_ESC "\047"
-#define STR_DEL "\007"
-#else
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-#endif
-
-#define STR_SPACE " "
-#define STR_EXCLAMATION_MARK "!"
-#define STR_QUOTATION_MARK "\""
-#define STR_NUMBER_SIGN "#"
-#define STR_DOLLAR_SIGN "$"
-#define STR_PERCENT_SIGN "%"
-#define STR_AMPERSAND "&"
-#define STR_APOSTROPHE "'"
-#define STR_LEFT_PARENTHESIS "("
-#define STR_RIGHT_PARENTHESIS ")"
-#define STR_ASTERISK "*"
-#define STR_PLUS "+"
-#define STR_COMMA ","
-#define STR_MINUS "-"
-#define STR_DOT "."
-#define STR_SLASH "/"
-#define STR_0 "0"
-#define STR_1 "1"
-#define STR_2 "2"
-#define STR_3 "3"
-#define STR_4 "4"
-#define STR_5 "5"
-#define STR_6 "6"
-#define STR_7 "7"
-#define STR_8 "8"
-#define STR_9 "9"
-#define STR_COLON ":"
-#define STR_SEMICOLON ";"
-#define STR_LESS_THAN_SIGN "<"
-#define STR_EQUALS_SIGN "="
-#define STR_GREATER_THAN_SIGN ">"
-#define STR_QUESTION_MARK "?"
-#define STR_COMMERCIAL_AT "@"
-#define STR_A "A"
-#define STR_B "B"
-#define STR_C "C"
-#define STR_D "D"
-#define STR_E "E"
-#define STR_F "F"
-#define STR_G "G"
-#define STR_H "H"
-#define STR_I "I"
-#define STR_J "J"
-#define STR_K "K"
-#define STR_L "L"
-#define STR_M "M"
-#define STR_N "N"
-#define STR_O "O"
-#define STR_P "P"
-#define STR_Q "Q"
-#define STR_R "R"
-#define STR_S "S"
-#define STR_T "T"
-#define STR_U "U"
-#define STR_V "V"
-#define STR_W "W"
-#define STR_X "X"
-#define STR_Y "Y"
-#define STR_Z "Z"
-#define STR_LEFT_SQUARE_BRACKET "["
-#define STR_BACKSLASH "\\"
-#define STR_RIGHT_SQUARE_BRACKET "]"
-#define STR_CIRCUMFLEX_ACCENT "^"
-#define STR_UNDERSCORE "_"
-#define STR_GRAVE_ACCENT "`"
-#define STR_a "a"
-#define STR_b "b"
-#define STR_c "c"
-#define STR_d "d"
-#define STR_e "e"
-#define STR_f "f"
-#define STR_g "g"
-#define STR_h "h"
-#define STR_i "i"
-#define STR_j "j"
-#define STR_k "k"
-#define STR_l "l"
-#define STR_m "m"
-#define STR_n "n"
-#define STR_o "o"
-#define STR_p "p"
-#define STR_q "q"
-#define STR_r "r"
-#define STR_s "s"
-#define STR_t "t"
-#define STR_u "u"
-#define STR_v "v"
-#define STR_w "w"
-#define STR_x "x"
-#define STR_y "y"
-#define STR_z "z"
-#define STR_LEFT_CURLY_BRACKET "{"
-#define STR_VERTICAL_LINE "|"
-#define STR_RIGHT_CURLY_BRACKET "}"
-#define STR_TILDE "~"
-
-#define STRING_ACCEPT0 "ACCEPT\0"
-#define STRING_COMMIT0 "COMMIT\0"
-#define STRING_F0 "F\0"
-#define STRING_FAIL0 "FAIL\0"
-#define STRING_MARK0 "MARK\0"
-#define STRING_PRUNE0 "PRUNE\0"
-#define STRING_SKIP0 "SKIP\0"
-#define STRING_THEN "THEN"
-
-#define STRING_alpha0 "alpha\0"
-#define STRING_lower0 "lower\0"
-#define STRING_upper0 "upper\0"
-#define STRING_alnum0 "alnum\0"
-#define STRING_ascii0 "ascii\0"
-#define STRING_blank0 "blank\0"
-#define STRING_cntrl0 "cntrl\0"
-#define STRING_digit0 "digit\0"
-#define STRING_graph0 "graph\0"
-#define STRING_print0 "print\0"
-#define STRING_punct0 "punct\0"
-#define STRING_space0 "space\0"
-#define STRING_word0 "word\0"
-#define STRING_xdigit "xdigit"
-
-#define STRING_DEFINE "DEFINE"
-
-#define STRING_CR_RIGHTPAR "CR)"
-#define STRING_LF_RIGHTPAR "LF)"
-#define STRING_CRLF_RIGHTPAR "CRLF)"
-#define STRING_ANY_RIGHTPAR "ANY)"
-#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
-#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
-#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#ifdef COMPILE_PCRE8
-#define STRING_UTF_RIGHTPAR "UTF8)"
-#endif
-#ifdef COMPILE_PCRE16
-#define STRING_UTF_RIGHTPAR "UTF16)"
-#endif
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
-
-#else /* SUPPORT_UTF */
-
-/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
-works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
-only. */
-
-#define CHAR_HT '\011'
-#define CHAR_VT '\013'
-#define CHAR_FF '\014'
-#define CHAR_CR '\015'
-#define CHAR_NL '\012'
-#define CHAR_BS '\010'
-#define CHAR_BEL '\007'
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-
-#define CHAR_SPACE '\040'
-#define CHAR_EXCLAMATION_MARK '\041'
-#define CHAR_QUOTATION_MARK '\042'
-#define CHAR_NUMBER_SIGN '\043'
-#define CHAR_DOLLAR_SIGN '\044'
-#define CHAR_PERCENT_SIGN '\045'
-#define CHAR_AMPERSAND '\046'
-#define CHAR_APOSTROPHE '\047'
-#define CHAR_LEFT_PARENTHESIS '\050'
-#define CHAR_RIGHT_PARENTHESIS '\051'
-#define CHAR_ASTERISK '\052'
-#define CHAR_PLUS '\053'
-#define CHAR_COMMA '\054'
-#define CHAR_MINUS '\055'
-#define CHAR_DOT '\056'
-#define CHAR_SLASH '\057'
-#define CHAR_0 '\060'
-#define CHAR_1 '\061'
-#define CHAR_2 '\062'
-#define CHAR_3 '\063'
-#define CHAR_4 '\064'
-#define CHAR_5 '\065'
-#define CHAR_6 '\066'
-#define CHAR_7 '\067'
-#define CHAR_8 '\070'
-#define CHAR_9 '\071'
-#define CHAR_COLON '\072'
-#define CHAR_SEMICOLON '\073'
-#define CHAR_LESS_THAN_SIGN '\074'
-#define CHAR_EQUALS_SIGN '\075'
-#define CHAR_GREATER_THAN_SIGN '\076'
-#define CHAR_QUESTION_MARK '\077'
-#define CHAR_COMMERCIAL_AT '\100'
-#define CHAR_A '\101'
-#define CHAR_B '\102'
-#define CHAR_C '\103'
-#define CHAR_D '\104'
-#define CHAR_E '\105'
-#define CHAR_F '\106'
-#define CHAR_G '\107'
-#define CHAR_H '\110'
-#define CHAR_I '\111'
-#define CHAR_J '\112'
-#define CHAR_K '\113'
-#define CHAR_L '\114'
-#define CHAR_M '\115'
-#define CHAR_N '\116'
-#define CHAR_O '\117'
-#define CHAR_P '\120'
-#define CHAR_Q '\121'
-#define CHAR_R '\122'
-#define CHAR_S '\123'
-#define CHAR_T '\124'
-#define CHAR_U '\125'
-#define CHAR_V '\126'
-#define CHAR_W '\127'
-#define CHAR_X '\130'
-#define CHAR_Y '\131'
-#define CHAR_Z '\132'
-#define CHAR_LEFT_SQUARE_BRACKET '\133'
-#define CHAR_BACKSLASH '\134'
-#define CHAR_RIGHT_SQUARE_BRACKET '\135'
-#define CHAR_CIRCUMFLEX_ACCENT '\136'
-#define CHAR_UNDERSCORE '\137'
-#define CHAR_GRAVE_ACCENT '\140'
-#define CHAR_a '\141'
-#define CHAR_b '\142'
-#define CHAR_c '\143'
-#define CHAR_d '\144'
-#define CHAR_e '\145'
-#define CHAR_f '\146'
-#define CHAR_g '\147'
-#define CHAR_h '\150'
-#define CHAR_i '\151'
-#define CHAR_j '\152'
-#define CHAR_k '\153'
-#define CHAR_l '\154'
-#define CHAR_m '\155'
-#define CHAR_n '\156'
-#define CHAR_o '\157'
-#define CHAR_p '\160'
-#define CHAR_q '\161'
-#define CHAR_r '\162'
-#define CHAR_s '\163'
-#define CHAR_t '\164'
-#define CHAR_u '\165'
-#define CHAR_v '\166'
-#define CHAR_w '\167'
-#define CHAR_x '\170'
-#define CHAR_y '\171'
-#define CHAR_z '\172'
-#define CHAR_LEFT_CURLY_BRACKET '\173'
-#define CHAR_VERTICAL_LINE '\174'
-#define CHAR_RIGHT_CURLY_BRACKET '\175'
-#define CHAR_TILDE '\176'
-
-#define STR_HT "\011"
-#define STR_VT "\013"
-#define STR_FF "\014"
-#define STR_CR "\015"
-#define STR_NL "\012"
-#define STR_BS "\010"
-#define STR_BEL "\007"
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-
-#define STR_SPACE "\040"
-#define STR_EXCLAMATION_MARK "\041"
-#define STR_QUOTATION_MARK "\042"
-#define STR_NUMBER_SIGN "\043"
-#define STR_DOLLAR_SIGN "\044"
-#define STR_PERCENT_SIGN "\045"
-#define STR_AMPERSAND "\046"
-#define STR_APOSTROPHE "\047"
-#define STR_LEFT_PARENTHESIS "\050"
-#define STR_RIGHT_PARENTHESIS "\051"
-#define STR_ASTERISK "\052"
-#define STR_PLUS "\053"
-#define STR_COMMA "\054"
-#define STR_MINUS "\055"
-#define STR_DOT "\056"
-#define STR_SLASH "\057"
-#define STR_0 "\060"
-#define STR_1 "\061"
-#define STR_2 "\062"
-#define STR_3 "\063"
-#define STR_4 "\064"
-#define STR_5 "\065"
-#define STR_6 "\066"
-#define STR_7 "\067"
-#define STR_8 "\070"
-#define STR_9 "\071"
-#define STR_COLON "\072"
-#define STR_SEMICOLON "\073"
-#define STR_LESS_THAN_SIGN "\074"
-#define STR_EQUALS_SIGN "\075"
-#define STR_GREATER_THAN_SIGN "\076"
-#define STR_QUESTION_MARK "\077"
-#define STR_COMMERCIAL_AT "\100"
-#define STR_A "\101"
-#define STR_B "\102"
-#define STR_C "\103"
-#define STR_D "\104"
-#define STR_E "\105"
-#define STR_F "\106"
-#define STR_G "\107"
-#define STR_H "\110"
-#define STR_I "\111"
-#define STR_J "\112"
-#define STR_K "\113"
-#define STR_L "\114"
-#define STR_M "\115"
-#define STR_N "\116"
-#define STR_O "\117"
-#define STR_P "\120"
-#define STR_Q "\121"
-#define STR_R "\122"
-#define STR_S "\123"
-#define STR_T "\124"
-#define STR_U "\125"
-#define STR_V "\126"
-#define STR_W "\127"
-#define STR_X "\130"
-#define STR_Y "\131"
-#define STR_Z "\132"
-#define STR_LEFT_SQUARE_BRACKET "\133"
-#define STR_BACKSLASH "\134"
-#define STR_RIGHT_SQUARE_BRACKET "\135"
-#define STR_CIRCUMFLEX_ACCENT "\136"
-#define STR_UNDERSCORE "\137"
-#define STR_GRAVE_ACCENT "\140"
-#define STR_a "\141"
-#define STR_b "\142"
-#define STR_c "\143"
-#define STR_d "\144"
-#define STR_e "\145"
-#define STR_f "\146"
-#define STR_g "\147"
-#define STR_h "\150"
-#define STR_i "\151"
-#define STR_j "\152"
-#define STR_k "\153"
-#define STR_l "\154"
-#define STR_m "\155"
-#define STR_n "\156"
-#define STR_o "\157"
-#define STR_p "\160"
-#define STR_q "\161"
-#define STR_r "\162"
-#define STR_s "\163"
-#define STR_t "\164"
-#define STR_u "\165"
-#define STR_v "\166"
-#define STR_w "\167"
-#define STR_x "\170"
-#define STR_y "\171"
-#define STR_z "\172"
-#define STR_LEFT_CURLY_BRACKET "\173"
-#define STR_VERTICAL_LINE "\174"
-#define STR_RIGHT_CURLY_BRACKET "\175"
-#define STR_TILDE "\176"
-
-#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
-#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
-#define STRING_F0 STR_F "\0"
-#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
-#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
-#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
-#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
-#define STRING_THEN STR_T STR_H STR_E STR_N
-
-#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
-#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
-#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
-#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
-#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
-#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
-#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
-#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
-#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
-#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
-#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
-#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
-#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
-
-#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
-
-#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
-#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
-#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
-#ifdef COMPILE_PCRE8
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
-#endif
-#ifdef COMPILE_PCRE16
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
-#endif
-#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
-#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
-
-#endif /* SUPPORT_UTF */
-
-/* Escape items that are just an encoding of a particular data value. */
-
-#ifndef ESC_e
-#define ESC_e CHAR_ESC
-#endif
-
-#ifndef ESC_f
-#define ESC_f CHAR_FF
-#endif
-
-#ifndef ESC_n
-#define ESC_n CHAR_NL
-#endif
-
-#ifndef ESC_r
-#define ESC_r CHAR_CR
-#endif
-
-/* We can't officially use ESC_t because it is a POSIX reserved identifier
-(presumably because of all the others like size_t). */
-
-#ifndef ESC_tee
-#define ESC_tee CHAR_HT
-#endif
-
-/* Codes for different types of Unicode property */
-
-#define PT_ANY 0 /* Any property - matches all chars */
-#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
-#define PT_GC 2 /* Specified general characteristic (e.g. L) */
-#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
-#define PT_SC 4 /* Script (e.g. Han) */
-#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */
-#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */
-#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
-#define PT_WORD 8 /* Word - L plus N plus underscore */
-
-/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
-contain characters with values greater than 255. */
-
-#define XCL_NOT 0x01 /* Flag: this is a negative class */
-#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
-
-#define XCL_END 0 /* Marks end of individual items */
-#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
-#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
-#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
-#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
-
-/* These are escaped items that aren't just an encoding of a particular data
-value such as \n. They must have non-zero values, as check_escape() returns
-their negation. Also, they must appear in the same order as in the opcode
-definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
-corresponds to "." in DOTALL mode rather than an escape sequence. It is also
-used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
-non-DOTALL mode, "." behaves like \N.
-
-The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
-when PCRE_UCP is set, when replacement of \d etc by \p sequences is required.
-They must be contiguous, and remain in order so that the replacements can be
-looked up from a table.
-
-The final escape must be ESC_REF as subsequent values are used for
-backreferences (\1, \2, \3, etc). There are two tests in the code for an escape
-greater than ESC_b and less than ESC_Z to detect the types that may be
-repeated. These are the types that consume characters. If any new escapes are
-put in between that don't consume a character, that code will have to change.
-*/
-
-enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
- ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
- ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
- ESC_E, ESC_Q, ESC_g, ESC_k,
- ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu,
- ESC_REF };
-
-/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
-OP_EOD must correspond in order to the list of escapes immediately above.
-
-*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
-that follow must also be updated to match. There are also tables called
-"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
-
-enum {
- OP_END, /* 0 End of pattern */
-
- /* Values corresponding to backslashed metacharacters */
-
- OP_SOD, /* 1 Start of data: \A */
- OP_SOM, /* 2 Start of match (subject + offset): \G */
- OP_SET_SOM, /* 3 Set start of match (\K) */
- OP_NOT_WORD_BOUNDARY, /* 4 \B */
- OP_WORD_BOUNDARY, /* 5 \b */
- OP_NOT_DIGIT, /* 6 \D */
- OP_DIGIT, /* 7 \d */
- OP_NOT_WHITESPACE, /* 8 \S */
- OP_WHITESPACE, /* 9 \s */
- OP_NOT_WORDCHAR, /* 10 \W */
- OP_WORDCHAR, /* 11 \w */
-
- OP_ANY, /* 12 Match any character except newline */
- OP_ALLANY, /* 13 Match any character */
- OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
- OP_NOTPROP, /* 15 \P (not Unicode property) */
- OP_PROP, /* 16 \p (Unicode property) */
- OP_ANYNL, /* 17 \R (any newline sequence) */
- OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
- OP_HSPACE, /* 19 \h (horizontal whitespace) */
- OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
- OP_VSPACE, /* 21 \v (vertical whitespace) */
- OP_EXTUNI, /* 22 \X (extended Unicode sequence */
- OP_EODN, /* 23 End of data or \n at end of data: \Z. */
- OP_EOD, /* 24 End of data: \z */
-
- OP_CIRC, /* 25 Start of line - not multiline */
- OP_CIRCM, /* 26 Start of line - multiline */
- OP_DOLL, /* 27 End of line - not multiline */
- OP_DOLLM, /* 28 End of line - multiline */
- OP_CHAR, /* 29 Match one character, casefully */
- OP_CHARI, /* 30 Match one character, caselessly */
- OP_NOT, /* 31 Match one character, not the given one, casefully */
- OP_NOTI, /* 32 Match one character, not the given one, caselessly */
-
- /* The following sets of 13 opcodes must always be kept in step because
- the offset from the first one is used to generate the others. */
-
- /**** Single characters, caseful, must precede the caseless ones ****/
-
- OP_STAR, /* 33 The maximizing and minimizing versions of */
- OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
- OP_PLUS, /* 35 the minimizing one second. */
- OP_MINPLUS, /* 36 */
- OP_QUERY, /* 37 */
- OP_MINQUERY, /* 38 */
-
- OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
- OP_MINUPTO, /* 40 */
- OP_EXACT, /* 41 Exactly n matches */
-
- OP_POSSTAR, /* 42 Possessified star, caseful */
- OP_POSPLUS, /* 43 Possessified plus, caseful */
- OP_POSQUERY, /* 44 Posesssified query, caseful */
- OP_POSUPTO, /* 45 Possessified upto, caseful */
-
- /**** Single characters, caseless, must follow the caseful ones */
-
- OP_STARI, /* 46 */
- OP_MINSTARI, /* 47 */
- OP_PLUSI, /* 48 */
- OP_MINPLUSI, /* 49 */
- OP_QUERYI, /* 50 */
- OP_MINQUERYI, /* 51 */
-
- OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
- OP_MINUPTOI, /* 53 */
- OP_EXACTI, /* 54 */
-
- OP_POSSTARI, /* 55 Possessified star, caseless */
- OP_POSPLUSI, /* 56 Possessified plus, caseless */
- OP_POSQUERYI, /* 57 Posesssified query, caseless */
- OP_POSUPTOI, /* 58 Possessified upto, caseless */
-
- /**** The negated ones must follow the non-negated ones, and match them ****/
- /**** Negated single character, caseful; must precede the caseless ones ****/
-
- OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
- OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
- OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
- OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
- OP_NOTQUERY, /* 63 */
- OP_NOTMINQUERY, /* 64 */
-
- OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
- OP_NOTMINUPTO, /* 66 */
- OP_NOTEXACT, /* 67 Exactly n matches */
-
- OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
- OP_NOTPOSPLUS, /* 69 */
- OP_NOTPOSQUERY, /* 70 */
- OP_NOTPOSUPTO, /* 71 */
-
- /**** Negated single character, caseless; must follow the caseful ones ****/
-
- OP_NOTSTARI, /* 72 */
- OP_NOTMINSTARI, /* 73 */
- OP_NOTPLUSI, /* 74 */
- OP_NOTMINPLUSI, /* 75 */
- OP_NOTQUERYI, /* 76 */
- OP_NOTMINQUERYI, /* 77 */
-
- OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
- OP_NOTMINUPTOI, /* 79 */
- OP_NOTEXACTI, /* 80 Exactly n matches */
-
- OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
- OP_NOTPOSPLUSI, /* 82 */
- OP_NOTPOSQUERYI, /* 83 */
- OP_NOTPOSUPTOI, /* 84 */
-
- /**** Character types ****/
-
- OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
- OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
- OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
- OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
- OP_TYPEQUERY, /* 89 */
- OP_TYPEMINQUERY, /* 90 */
-
- OP_TYPEUPTO, /* 91 From 0 to n matches */
- OP_TYPEMINUPTO, /* 92 */
- OP_TYPEEXACT, /* 93 Exactly n matches */
-
- OP_TYPEPOSSTAR, /* 94 Possessified versions */
- OP_TYPEPOSPLUS, /* 95 */
- OP_TYPEPOSQUERY, /* 96 */
- OP_TYPEPOSUPTO, /* 97 */
-
- /* These are used for character classes and back references; only the
- first six are the same as the sets above. */
-
- OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
- OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
- OP_CRPLUS, /* 100 the minimizing one second. These codes must */
- OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
- OP_CRQUERY, /* 102 */
- OP_CRMINQUERY, /* 103 */
-
- OP_CRRANGE, /* 104 These are different to the three sets above. */
- OP_CRMINRANGE, /* 105 */
-
- /* End of quantifier opcodes */
-
- OP_CLASS, /* 106 Match a character class, chars < 256 only */
- OP_NCLASS, /* 107 Same, but the bitmap was created from a negative
- class - the difference is relevant only when a
- character > 255 is encountered. */
- OP_XCLASS, /* 108 Extended class for handling > 255 chars within the
- class. This does both positive and negative. */
- OP_REF, /* 109 Match a back reference, casefully */
- OP_REFI, /* 110 Match a back reference, caselessly */
- OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */
- OP_CALLOUT, /* 112 Call out to external function if provided */
-
- OP_ALT, /* 113 Start of alternation */
- OP_KET, /* 114 End of group that doesn't have an unbounded repeat */
- OP_KETRMAX, /* 115 These two must remain together and in this */
- OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */
- OP_KETRPOS, /* 117 Possessive unlimited repeat. */
-
- /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
- asserts must remain in order. */
-
- OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */
- OP_ASSERT, /* 119 Positive lookahead */
- OP_ASSERT_NOT, /* 120 Negative lookahead */
- OP_ASSERTBACK, /* 121 Positive lookbehind */
- OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */
-
- /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
- after the assertions, with ONCE first, as there's a test for >= ONCE for a
- subpattern that isn't an assertion. The POS versions must immediately follow
- the non-POS versions in each case. */
-
- OP_ONCE, /* 123 Atomic group, contains captures */
- OP_ONCE_NC, /* 124 Atomic group containing no captures */
- OP_BRA, /* 125 Start of non-capturing bracket */
- OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */
- OP_CBRA, /* 127 Start of capturing bracket */
- OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */
- OP_COND, /* 129 Conditional group */
-
- /* These five must follow the previous five, in the same order. There's a
- check for >= SBRA to distinguish the two sets. */
-
- OP_SBRA, /* 130 Start of non-capturing bracket, check empty */
- OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */
- OP_SCBRA, /* 132 Start of capturing bracket, check empty */
- OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
- OP_SCOND, /* 134 Conditional group, check empty */
-
- /* The next two pairs must (respectively) be kept together. */
-
- OP_CREF, /* 135 Used to hold a capture number as condition */
- OP_NCREF, /* 136 Same, but generated by a name reference*/
- OP_RREF, /* 137 Used to hold a recursion number as condition */
- OP_NRREF, /* 138 Same, but generated by a name reference*/
- OP_DEF, /* 139 The DEFINE condition */
-
- OP_BRAZERO, /* 140 These two must remain together and in this */
- OP_BRAMINZERO, /* 141 order. */
- OP_BRAPOSZERO, /* 142 */
-
- /* These are backtracking control verbs */
-
- OP_MARK, /* 143 always has an argument */
- OP_PRUNE, /* 144 */
- OP_PRUNE_ARG, /* 145 same, but with argument */
- OP_SKIP, /* 146 */
- OP_SKIP_ARG, /* 147 same, but with argument */
- OP_THEN, /* 148 */
- OP_THEN_ARG, /* 149 same, but with argument */
- OP_COMMIT, /* 150 */
-
- /* These are forced failure and success verbs */
-
- OP_FAIL, /* 151 */
- OP_ACCEPT, /* 152 */
- OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
- OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
-
- /* This is used to skip a subpattern with a {0} quantifier */
-
- OP_SKIPZERO, /* 155 */
-
- /* This is not an opcode, but is used to check that tables indexed by opcode
- are the correct length, in order to catch updating errors - there have been
- some in the past. */
-
- OP_TABLE_LENGTH
-};
-
-/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
-definitions that follow must also be updated to match. There are also tables
-called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
-
-
-/* This macro defines textual names for all the opcodes. These are used only
-for debugging, and some of them are only partial names. The macro is referenced
-only in pcre_printint.c, which fills out the full names in many cases (and in
-some cases doesn't actually use these names at all). */
-
-#define OP_NAME_LIST \
- "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
- "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
- "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
- "extuni", "\\Z", "\\z", \
- "^", "^", "$", "$", "char", "chari", "not", "noti", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Refi", \
- "Recurse", "Callout", \
- "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
- "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
- "Once", "Once_NC", \
- "Bra", "BraPos", "CBra", "CBraPos", \
- "Cond", \
- "SBra", "SBraPos", "SCBra", "SCBraPos", \
- "SCond", \
- "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
- "Brazero", "Braminzero", "Braposzero", \
- "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
- "*THEN", "*THEN", "*COMMIT", "*FAIL", \
- "*ACCEPT", "*ASSERT_ACCEPT", \
- "Close", "Skip zero"
-
-
-/* This macro defines the length of fixed length operations in the compiled
-regex. The lengths are used when searching for specific things, and also in the
-debugging printing of a compiled regex. We use a macro so that it can be
-defined close to the definitions of the opcodes themselves.
-
-As things have been extended, some of these are no longer fixed lenths, but are
-minima instead. For example, the length of a single-character repeat may vary
-in UTF-8 mode. The code that uses this table must know about such things. */
-
-#define OP_LENGTHS \
- 1, /* End */ \
- 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
- 1, 1, 1, /* Any, AllAny, Anybyte */ \
- 3, 3, /* \P, \p */ \
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
- 1, /* \X */ \
- 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
- 2, /* Char - the minimum length */ \
- 2, /* Chari - the minimum length */ \
- 2, /* not */ \
- 2, /* noti */ \
- /* Positive single-char repeats ** These are */ \
- 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
- 2+IMM2_SIZE, /* exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
- 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
- 2+IMM2_SIZE, /* exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
- /* Negative single-char repeats - only for chars < 256 */ \
- 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
- 2+IMM2_SIZE, /* NOT exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
- 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
- 2+IMM2_SIZE, /* NOT exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
- /* Positive type repeats */ \
- 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
- 2+IMM2_SIZE, /* Type exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
- /* Character class & ref repeats */ \
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
- 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
- 1+(32/sizeof(pcre_uchar)), /* CLASS */ \
- 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
- 0, /* XCLASS - variable length */ \
- 1+IMM2_SIZE, /* REF */ \
- 1+IMM2_SIZE, /* REFI */ \
- 1+LINK_SIZE, /* RECURSE */ \
- 2+2*LINK_SIZE, /* CALLOUT */ \
- 1+LINK_SIZE, /* Alt */ \
- 1+LINK_SIZE, /* Ket */ \
- 1+LINK_SIZE, /* KetRmax */ \
- 1+LINK_SIZE, /* KetRmin */ \
- 1+LINK_SIZE, /* KetRpos */ \
- 1+LINK_SIZE, /* Reverse */ \
- 1+LINK_SIZE, /* Assert */ \
- 1+LINK_SIZE, /* Assert not */ \
- 1+LINK_SIZE, /* Assert behind */ \
- 1+LINK_SIZE, /* Assert behind not */ \
- 1+LINK_SIZE, /* ONCE */ \
- 1+LINK_SIZE, /* ONCE_NC */ \
- 1+LINK_SIZE, /* BRA */ \
- 1+LINK_SIZE, /* BRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
- 1+LINK_SIZE, /* COND */ \
- 1+LINK_SIZE, /* SBRA */ \
- 1+LINK_SIZE, /* SBRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
- 1+LINK_SIZE, /* SCOND */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
- 1, /* DEF */ \
- 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
- 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
- 1, 3, /* SKIP, SKIP_ARG */ \
- 1, 3, /* THEN, THEN_ARG */ \
- 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
- 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */
-
-/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
-condition. */
-
-#define RREF_ANY 0xffff
-
-/* Compile time error code numbers. They are given names so that they can more
-easily be tracked. When a new number is added, the table called eint in
-pcreposix.c must be updated. */
-
-enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
- ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
- ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
- ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
- ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
- ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
- ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
- ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, 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 };
-
-/* The real format of the start of the pcre block; the index of names and the
-code vector run on as long as necessary after the end. We store an explicit
-offset to the name table so that if a regex is compiled on one host, saved, and
-then run on another where the size of pointers is different, all might still
-be well. For the case of compiled-on-4 and run-on-8, we include an extra
-pointer that is always NULL. For future-proofing, a few dummy fields were
-originally included - even though you can never get this planning right - but
-there is only one left now.
-
-NOTE NOTE NOTE:
-Because people can now save and re-use compiled patterns, any additions to this
-structure should be made at the end, and something earlier (e.g. a new
-flag in the options or one of the dummy fields) should indicate that the new
-fields are present. Currently PCRE always sets the dummy fields to zero.
-NOTE NOTE NOTE
-*/
-
-#ifdef COMPILE_PCRE8
-#define REAL_PCRE real_pcre
-#else
-#define REAL_PCRE real_pcre16
-#endif
-
-typedef struct REAL_PCRE {
- pcre_uint32 magic_number;
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
- pcre_uint16 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 */
- const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- const pcre_uint8 *nullpad; /* NULL padding */
-} REAL_PCRE;
-
-/* The format of the block used to store data from pcre_study(). The same
-remark (see NOTE above) about extending this structure applies. */
-
-typedef struct pcre_study_data {
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 flags; /* Private flags */
- pcre_uint8 start_bits[32]; /* Starting char bits */
- pcre_uint32 minlength; /* Minimum subject length */
-} pcre_study_data;
-
-/* Structure for building a chain of open capturing subpatterns during
-compiling, so that instructions to close them can be compiled when (*ACCEPT) is
-encountered. This is also used to identify subpatterns that contain recursive
-back references to themselves, so that they can be made atomic. */
-
-typedef struct open_capitem {
- struct open_capitem *next; /* Chain link */
- pcre_uint16 number; /* Capture number */
- pcre_uint16 flag; /* Set TRUE if recursive back ref */
-} open_capitem;
-
-/* Structure for passing "static" information around between the functions
-doing the compiling, so that they are thread-safe. */
-
-typedef struct compile_data {
- const pcre_uint8 *lcc; /* Points to lower casing table */
- const pcre_uint8 *fcc; /* Points to case-flipping table */
- const pcre_uint8 *cbits; /* Points to character type table */
- const pcre_uint8 *ctypes; /* Points to table of type maps */
- const pcre_uchar *start_workspace;/* The start of working space */
- const pcre_uchar *start_code; /* The start of the compiled code */
- const pcre_uchar *start_pattern; /* The start of the pattern */
- const pcre_uchar *end_pattern; /* The end of the pattern */
- open_capitem *open_caps; /* Chain of open capture items */
- pcre_uchar *hwm; /* High watermark of workspace */
- pcre_uchar *name_table; /* The name/number table */
- int names_found; /* Number of entries so far */
- int name_entry_size; /* Size of each entry */
- int workspace_size; /* Size of workspace */
- int bracount; /* Count of capturing parens as we compile */
- int final_bracount; /* Saved value after first pass */
- int max_lookbehind; /* Maximum lookbehind (characters) */
- int top_backref; /* Maximum back reference */
- unsigned int backref_map; /* Bitmap of low back refs */
- int assert_depth; /* Depth of nested assertions */
- int external_options; /* External (initial) options */
- int external_flags; /* External flag bits to be set */
- int req_varyopt; /* "After variable item" flag for reqbyte */
- BOOL had_accept; /* (*ACCEPT) encountered */
- BOOL check_lookbehind; /* Lookbehinds need later checking */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- pcre_uchar nl[4]; /* Newline string when fixed length */
-} compile_data;
-
-/* Structure for maintaining a chain of pointers to the currently incomplete
-branches, for testing for left recursion while compiling. */
-
-typedef struct branch_chain {
- struct branch_chain *outer;
- pcre_uchar *current_branch;
-} branch_chain;
-
-/* Structure for items in a linked list that represents an explicit recursive
-call within the pattern; used by pcre_exec(). */
-
-typedef struct recursion_info {
- struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
- int group_num; /* Number of group that was called */
- int *offset_save; /* Pointer to start of saved offsets */
- int saved_max; /* Number of saved offsets */
- PCRE_PUCHAR subject_position; /* Position at start of recursion */
-} recursion_info;
-
-/* A similar structure for pcre_dfa_exec(). */
-
-typedef struct dfa_recursion_info {
- struct dfa_recursion_info *prevrec;
- int group_num;
- PCRE_PUCHAR subject_position;
-} dfa_recursion_info;
-
-/* Structure for building a chain of data for holding the values of the subject
-pointer at the start of each subpattern, so as to detect when an empty string
-has been matched by a subpattern - to break infinite loops; used by
-pcre_exec(). */
-
-typedef struct eptrblock {
- struct eptrblock *epb_prev;
- PCRE_PUCHAR epb_saved_eptr;
-} eptrblock;
-
-
-/* Structure for passing "static" information around between the functions
-doing traditional NFA matching, so that they are thread-safe. */
-
-typedef struct match_data {
- unsigned long int match_call_count; /* As it says */
- unsigned long int match_limit; /* As it says */
- unsigned long int match_limit_recursion; /* As it says */
- int *offset_vector; /* Offset vector */
- int offset_end; /* One past the end */
- int offset_max; /* The maximum usable for return data */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- int name_count; /* Number of names in name table */
- int name_entry_size; /* Size of entry in names table */
- pcre_uchar *name_table; /* Table of names */
- pcre_uchar nl[4]; /* Newline string when fixed */
- const pcre_uint8 *lcc; /* Points to lower casing table */
- const pcre_uint8 *fcc; /* Points to case-flipping table */
- const pcre_uint8 *ctypes; /* Points to table of type maps */
- BOOL offset_overflow; /* Set if too many extractions */
- BOOL notbol; /* NOTBOL flag */
- BOOL noteol; /* NOTEOL flag */
- BOOL utf; /* UTF-8 / UTF-16 flag */
- BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
- BOOL use_ucp; /* PCRE_UCP flag */
- BOOL endonly; /* Dollar not before final \n */
- BOOL notempty; /* Empty string match not wanted */
- BOOL notempty_atstart; /* Empty string match at start not wanted */
- BOOL hitend; /* Hit the end of the subject at some point */
- BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
- BOOL hasthen; /* Pattern contains (*THEN) */
- BOOL ignore_skip_arg; /* For re-run when SKIP name not found */
- const pcre_uchar *start_code; /* For use when recursing */
- PCRE_PUCHAR start_subject; /* Start of the subject string */
- PCRE_PUCHAR end_subject; /* End of the subject string */
- PCRE_PUCHAR start_match_ptr; /* Start of matched string */
- PCRE_PUCHAR end_match_ptr; /* Subject position at end match */
- PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */
- int partial; /* PARTIAL options */
- int end_offset_top; /* Highwater mark at end of match */
- int capture_last; /* Most recent capture number */
- int start_offset; /* The start offset value */
- int match_function_type; /* Set for certain special calls of MATCH() */
- eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
- int eptrn; /* Next free eptrblock */
- recursion_info *recursive; /* Linked list of recursion data */
- void *callout_data; /* To pass back to callouts */
- const pcre_uchar *mark; /* Mark pointer to pass back on success */
- const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
- const pcre_uchar *once_target; /* Where to back up to for atomic groups */
-#ifdef NO_RECURSE
- void *match_frames_base; /* For remembering malloc'd frames */
-#endif
-} match_data;
-
-/* A similar structure is used for the same purpose by the DFA matching
-functions. */
-
-typedef struct dfa_match_data {
- const pcre_uchar *start_code; /* Start of the compiled pattern */
- const pcre_uchar *start_subject ; /* Start of the subject string */
- const pcre_uchar *end_subject; /* End of subject string */
- const pcre_uchar *start_used_ptr; /* Earliest consulted character */
- const pcre_uint8 *tables; /* Character tables */
- int start_offset; /* The start offset value */
- int moptions; /* Match options */
- int poptions; /* Pattern options */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- pcre_uchar nl[4]; /* Newline string when fixed */
- void *callout_data; /* To pass back to callouts */
- dfa_recursion_info *recursive; /* Linked list of recursion data */
-} dfa_match_data;
-
-/* Bit definitions for entries in the pcre_ctypes table. */
-
-#define ctype_space 0x01
-#define ctype_letter 0x02
-#define ctype_digit 0x04
-#define ctype_xdigit 0x08
-#define ctype_word 0x10 /* alphanumeric or '_' */
-#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
-
-/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
-of bits for a class map. Some classes are built by combining these tables. */
-
-#define cbit_space 0 /* [:space:] or \s */
-#define cbit_xdigit 32 /* [:xdigit:] */
-#define cbit_digit 64 /* [:digit:] or \d */
-#define cbit_upper 96 /* [:upper:] */
-#define cbit_lower 128 /* [:lower:] */
-#define cbit_word 160 /* [:word:] or \w */
-#define cbit_graph 192 /* [:graph:] */
-#define cbit_print 224 /* [:print:] */
-#define cbit_punct 256 /* [:punct:] */
-#define cbit_cntrl 288 /* [:cntrl:] */
-#define cbit_length 320 /* Length of the cbits table */
-
-/* Offsets of the various tables from the base tables pointer, and
-total length. */
-
-#define lcc_offset 0
-#define fcc_offset 256
-#define cbits_offset 512
-#define ctypes_offset (cbits_offset + cbit_length)
-#define tables_length (ctypes_offset + 256)
-
-/* Internal function and data prefixes. */
-
-#ifdef COMPILE_PCRE8
-#ifndef PUBL
-#define PUBL(name) pcre_##name
-#endif
-#ifndef PRIV
-#define PRIV(name) _pcre_##name
-#endif
-#else /* COMPILE_PCRE8 */
-#ifdef COMPILE_PCRE16
-#ifndef PUBL
-#define PUBL(name) pcre16_##name
-#endif
-#ifndef PRIV
-#define PRIV(name) _pcre16_##name
-#endif
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE16 */
-#endif /* COMPILE_PCRE8 */
-
-/* Layout of the UCP type table that translates property names into types and
-codes. Each entry used to point directly to a name, but to reduce the number of
-relocations in shared libraries, it now has an offset into a single string
-instead. */
-
-typedef struct {
- pcre_uint16 name_offset;
- pcre_uint16 type;
- pcre_uint16 value;
-} ucp_type_table;
-
-
-/* Internal shared data tables. These are tables that are used by more than one
-of the exported public functions. They have to be "external" in the C sense,
-but are not part of the PCRE public API. The data for these tables is in the
-pcre_tables.c module. */
-
-#ifdef COMPILE_PCRE8
-
-extern const int PRIV(utf8_table1)[];
-extern const int PRIV(utf8_table1_size);
-extern const int PRIV(utf8_table2)[];
-extern const int PRIV(utf8_table3)[];
-extern const pcre_uint8 PRIV(utf8_table4)[];
-
-#endif /* COMPILE_PCRE8 */
-
-extern const char PRIV(utt_names)[];
-extern const ucp_type_table PRIV(utt)[];
-extern const int PRIV(utt_size);
-
-extern const pcre_uint8 PRIV(default_tables)[];
-
-extern const pcre_uint8 PRIV(OP_lengths)[];
-
-
-/* Internal shared functions. These are functions that are used by more than
-one of the exported public functions. They have to be "external" in the C
-sense, but are not part of the PCRE public API. */
-
-/* String comparison functions. */
-#ifdef COMPILE_PCRE8
-
-#define STRCMP_UC_UC(str1, str2) \
- strcmp((char *)(str1), (char *)(str2))
-#define STRCMP_UC_C8(str1, str2) \
- strcmp((char *)(str1), (str2))
-#define STRNCMP_UC_UC(str1, str2, num) \
- strncmp((char *)(str1), (char *)(str2), (num))
-#define STRNCMP_UC_C8(str1, str2, num) \
- strncmp((char *)(str1), (str2), (num))
-#define STRLEN_UC(str) strlen((const char *)str)
-
-#else
-
-extern int PRIV(strcmp_uc_uc)(const pcre_uchar *,
- const pcre_uchar *);
-extern int PRIV(strcmp_uc_c8)(const pcre_uchar *,
- const char *);
-extern int PRIV(strncmp_uc_uc)(const pcre_uchar *,
- const pcre_uchar *, unsigned int num);
-extern int PRIV(strncmp_uc_c8)(const pcre_uchar *,
- const char *, unsigned int num);
-extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str);
-
-#define STRCMP_UC_UC(str1, str2) \
- PRIV(strcmp_uc_uc)((str1), (str2))
-#define STRCMP_UC_C8(str1, str2) \
- PRIV(strcmp_uc_c8)((str1), (str2))
-#define STRNCMP_UC_UC(str1, str2, num) \
- PRIV(strncmp_uc_uc)((str1), (str2), (num))
-#define STRNCMP_UC_C8(str1, str2, num) \
- PRIV(strncmp_uc_c8)((str1), (str2), (num))
-#define STRLEN_UC(str) PRIV(strlen_uc)(str)
-
-#endif /* COMPILE_PCRE8 */
-
-extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
-extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
- int *, BOOL);
-extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
-extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
-extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
- int *, BOOL);
-extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL);
-
-#ifdef SUPPORT_JIT
-extern void PRIV(jit_compile)(const REAL_PCRE *,
- PUBL(extra) *, int);
-extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *,
- const pcre_uchar *, int, int, int, int *, int);
-extern void PRIV(jit_free)(void *);
-extern int PRIV(jit_get_size)(void *);
-extern const char* PRIV(jit_get_target)(void);
-#endif
-
-/* Unicode character database (UCD) */
-
-extern const int PRIV(ucp_gentype)[];
-#ifdef SUPPORT_JIT
-extern const int PRIV(ucp_typerange)[];
-#endif
-
-#ifdef SUPPORT_UCP
-/* UCD access macros */
-
-unsigned int _pcre_ucp_othercase(const unsigned int c);
-
-#define UCD_CHARTYPE(ch) (pcre_uint8)g_unichar_type((gunichar)(ch))
-#define UCD_SCRIPT(ch) (pcre_uint8)g_unichar_get_script((gunichar)(ch))
-#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
-#define UCD_OTHERCASE(ch) (_pcre_ucp_othercase(ch))
-
-#endif /* SUPPORT_UCP */
-
-#endif
-
-/* End of pcre_internal.h */
diff --git a/glib/pcre/pcre_jit_compile.c b/glib/pcre/pcre_jit_compile.c
deleted file mode 100644
index d7233832f..000000000
--- a/glib/pcre/pcre_jit_compile.c
+++ /dev/null
@@ -1,7497 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
- The machine code generator part (this module) was written by Zoltan Herczeg
- Copyright (c) 2010-2012
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-#ifdef SUPPORT_JIT
-
-/* All-in-one: Since we use the JIT compiler only from here,
-we just include it. This way we don't need to touch the build
-system files. */
-
-#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
-#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
-#define SLJIT_CONFIG_AUTO 1
-#define SLJIT_CONFIG_STATIC 1
-#define SLJIT_VERBOSE 0
-#define SLJIT_DEBUG 0
-
-#include "sljit/sljitLir.c"
-
-#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
-#error Unsupported architecture
-#endif
-
-/* Allocate memory on the stack. Fast, but limited size. */
-#define LOCAL_SPACE_SIZE 32768
-
-#define STACK_GROWTH_RATE 8192
-
-/* Enable to check that the allocation could destroy temporaries. */
-#if defined SLJIT_DEBUG && SLJIT_DEBUG
-#define DESTROY_REGISTERS 1
-#endif
-
-/*
-Short summary about the backtracking mechanism empolyed by the jit code generator:
-
-The code generator follows the recursive nature of the PERL compatible regular
-expressions. The basic blocks of regular expressions are condition checkers
-whose execute different commands depending on the result of the condition check.
-The relationship between the operators can be horizontal (concatenation) and
-vertical (sub-expression) (See struct backtrack_common for more details).
-
- 'ab' - 'a' and 'b' regexps are concatenated
- 'a+' - 'a' is the sub-expression of the '+' operator
-
-The condition checkers are boolean (true/false) checkers. Machine code is generated
-for the checker itself and for the actions depending on the result of the checker.
-The 'true' case is called as the try path (expected path), and the other is called as
-the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
-branches on the try path.
-
- Greedy star operator (*) :
- Try path: match happens.
- Backtrack path: match failed.
- Non-greedy star operator (*?) :
- Try path: no need to perform a match.
- Backtrack path: match is required.
-
-The following example shows how the code generated for a capturing bracket
-with two alternatives. Let A, B, C, D are arbirary regular expressions, and
-we have the following regular expression:
-
- A(B|C)D
-
-The generated code will be the following:
-
- A try path
- '(' try path (pushing arguments to the stack)
- B try path
- ')' try path (pushing arguments to the stack)
- D try path
- return with successful match
-
- D backtrack path
- ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
- B backtrack path
- C expected path
- jump to D try path
- C backtrack path
- A backtrack path
-
- Notice, that the order of backtrack code paths are the opposite of the fast
- code paths. In this way the topmost value on the stack is always belong
- to the current backtrack code path. The backtrack path must check
- whether there is a next alternative. If so, it needs to jump back to
- the try path eventually. Otherwise it needs to clear out its own stack
- frame and continue the execution on the backtrack code paths.
-*/
-
-/*
-Saved stack frames:
-
-Atomic blocks and asserts require reloading the values of local variables
-when the backtrack mechanism performed. Because of OP_RECURSE, the locals
-are not necessarly known in compile time, thus we need a dynamic restore
-mechanism.
-
-The stack frames are stored in a chain list, and have the following format:
-([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
-
-Thus we can restore the locals to a particular point in the stack.
-*/
-
-typedef struct jit_arguments {
- /* Pointers first. */
- struct sljit_stack *stack;
- const pcre_uchar *str;
- const pcre_uchar *begin;
- const pcre_uchar *end;
- int *offsets;
- pcre_uchar *uchar_ptr;
- pcre_uchar *mark_ptr;
- /* Everything else after. */
- int offsetcount;
- int calllimit;
- pcre_uint8 notbol;
- pcre_uint8 noteol;
- pcre_uint8 notempty;
- pcre_uint8 notempty_atstart;
-} jit_arguments;
-
-typedef struct executable_functions {
- void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
- PUBL(jit_callback) callback;
- void *userdata;
- sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
-} executable_functions;
-
-typedef struct jump_list {
- struct sljit_jump *jump;
- struct jump_list *next;
-} jump_list;
-
-enum stub_types { stack_alloc };
-
-typedef struct stub_list {
- enum stub_types type;
- int data;
- struct sljit_jump *start;
- struct sljit_label *leave;
- struct stub_list *next;
-} stub_list;
-
-typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
-
-/* The following structure is the key data type for the recursive
-code generator. It is allocated by compile_trypath, and contains
-the aguments for compile_backtrackpath. Must be the first member
-of its descendants. */
-typedef struct backtrack_common {
- /* Concatenation stack. */
- struct backtrack_common *prev;
- jump_list *nextbacktracks;
- /* Internal stack (for component operators). */
- struct backtrack_common *top;
- jump_list *topbacktracks;
- /* Opcode pointer. */
- pcre_uchar *cc;
-} backtrack_common;
-
-typedef struct assert_backtrack {
- backtrack_common common;
- jump_list *condfailed;
- /* Less than 0 (-1) if a frame is not needed. */
- int framesize;
- /* Points to our private memory word on the stack. */
- int localptr;
- /* For iterators. */
- struct sljit_label *trypath;
-} assert_backtrack;
-
-typedef struct bracket_backtrack {
- backtrack_common common;
- /* Where to coninue if an alternative is successfully matched. */
- struct sljit_label *alttrypath;
- /* For rmin and rmax iterators. */
- struct sljit_label *recursivetrypath;
- /* For greedy ? operator. */
- struct sljit_label *zerotrypath;
- /* Contains the branches of a failed condition. */
- union {
- /* Both for OP_COND, OP_SCOND. */
- jump_list *condfailed;
- assert_backtrack *assert;
- /* For OP_ONCE. -1 if not needed. */
- int framesize;
- } u;
- /* Points to our private memory word on the stack. */
- int localptr;
-} bracket_backtrack;
-
-typedef struct bracketpos_backtrack {
- backtrack_common common;
- /* Points to our private memory word on the stack. */
- int localptr;
- /* Reverting stack is needed. */
- int framesize;
- /* Allocated stack size. */
- int stacksize;
-} bracketpos_backtrack;
-
-typedef struct braminzero_backtrack {
- backtrack_common common;
- struct sljit_label *trypath;
-} braminzero_backtrack;
-
-typedef struct iterator_backtrack {
- backtrack_common common;
- /* Next iteration. */
- struct sljit_label *trypath;
-} iterator_backtrack;
-
-typedef struct recurse_entry {
- struct recurse_entry *next;
- /* Contains the function entry. */
- struct sljit_label *entry;
- /* Collects the calls until the function is not created. */
- jump_list *calls;
- /* Points to the starting opcode. */
- int start;
-} recurse_entry;
-
-typedef struct recurse_backtrack {
- backtrack_common common;
-} recurse_backtrack;
-
-typedef struct compiler_common {
- struct sljit_compiler *compiler;
- pcre_uchar *start;
-
- /* Opcode local area direct map. */
- int *localptrs;
- int cbraptr;
- /* OVector 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;
- /* First inspected character for partial matching. */
- int start_used_ptr;
- /* Starting pointer for partial soft matches. */
- int hit_start;
- /* End pointer of the first line. */
- int first_line_end;
- /* Points to the marked string. */
- int mark_ptr;
-
- /* Other */
- const pcre_uint8 *fcc;
- sljit_w lcc;
- int mode;
- int nltype;
- int newline;
- int bsr_nltype;
- int endonly;
- BOOL has_set_som;
- sljit_w ctypes;
- sljit_uw name_table;
- sljit_w name_count;
- sljit_w name_entry_size;
-
- /* Labels and jump lists. */
- struct sljit_label *partialmatchlabel;
- struct sljit_label *leavelabel;
- struct sljit_label *acceptlabel;
- stub_list *stubs;
- recurse_entry *entries;
- recurse_entry *currententry;
- jump_list *partialmatch;
- jump_list *leave;
- jump_list *accept;
- jump_list *calllimit;
- jump_list *stackalloc;
- jump_list *revertframes;
- jump_list *wordboundary;
- jump_list *anynewline;
- jump_list *hspace;
- jump_list *vspace;
- jump_list *casefulcmp;
- jump_list *caselesscmp;
- BOOL jscript_compat;
-#ifdef SUPPORT_UTF
- BOOL utf;
-#ifdef SUPPORT_UCP
- BOOL use_ucp;
-#endif
- jump_list *utfreadchar;
-#ifdef COMPILE_PCRE8
- jump_list *utfreadtype8;
-#endif
-#endif /* SUPPORT_UTF */
-#ifdef SUPPORT_UCP
- jump_list *getunichartype;
- jump_list *getunichartype_2;
- jump_list *getunicharscript;
-#endif
-} compiler_common;
-
-/* For byte_sequence_compare. */
-
-typedef struct compare_context {
- int length;
- int sourcereg;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- int ucharptr;
- union {
- sljit_i asint;
- sljit_uh asushort;
-#ifdef COMPILE_PCRE8
- sljit_ub asbyte;
- sljit_ub asuchars[4];
-#else
-#ifdef COMPILE_PCRE16
- sljit_uh asuchars[2];
-#endif
-#endif
- } c;
- union {
- sljit_i asint;
- sljit_uh asushort;
-#ifdef COMPILE_PCRE8
- sljit_ub asbyte;
- sljit_ub asuchars[4];
-#else
-#ifdef COMPILE_PCRE16
- sljit_uh asuchars[2];
-#endif
-#endif
- } oc;
-#endif
-} compare_context;
-
-enum {
- frame_end = 0,
- frame_setstrbegin = -1,
- frame_setmark = -2
-};
-
-/* Undefine sljit macros. */
-#undef CMP
-
-/* Used for accessing the elements of the stack. */
-#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w))
-
-#define TMP1 SLJIT_TEMPORARY_REG1
-#define TMP2 SLJIT_TEMPORARY_REG3
-#define TMP3 SLJIT_TEMPORARY_EREG2
-#define STR_PTR SLJIT_SAVED_REG1
-#define STR_END SLJIT_SAVED_REG2
-#define STACK_TOP SLJIT_TEMPORARY_REG2
-#define STACK_LIMIT SLJIT_SAVED_REG3
-#define ARGUMENTS SLJIT_SAVED_EREG1
-#define CALL_COUNT SLJIT_SAVED_EREG2
-#define RETURN_ADDR SLJIT_TEMPORARY_EREG1
-
-/* Locals layout. */
-/* These two locals can be used by the current opcode. */
-#define LOCALS0 (0 * sizeof(sljit_w))
-#define LOCALS1 (1 * sizeof(sljit_w))
-/* Two local variables for possessive quantifiers (char1 cannot use them). */
-#define POSSESSIVE0 (2 * sizeof(sljit_w))
-#define POSSESSIVE1 (3 * sizeof(sljit_w))
-/* Max limit of recursions. */
-#define CALL_LIMIT (4 * sizeof(sljit_w))
-/* The output vector is stored on the stack, and contains pointers
-to characters. The vector data is divided into two groups: the first
-group contains the start / end character pointers, and the second is
-the start pointers when the end of the capturing group has not yet reached. */
-#define OVECTOR_START (common->ovector_start)
-#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w))
-#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w))
-#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start])
-
-#ifdef COMPILE_PCRE8
-#define MOV_UCHAR SLJIT_MOV_UB
-#define MOVU_UCHAR SLJIT_MOVU_UB
-#else
-#ifdef COMPILE_PCRE16
-#define MOV_UCHAR SLJIT_MOV_UH
-#define MOVU_UCHAR SLJIT_MOVU_UH
-#else
-#error Unsupported compiling mode
-#endif
-#endif
-
-/* Shortcuts. */
-#define DEFINE_COMPILER \
- struct sljit_compiler *compiler = common->compiler
-#define OP1(op, dst, dstw, src, srcw) \
- sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
-#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
- sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
-#define LABEL() \
- sljit_emit_label(compiler)
-#define JUMP(type) \
- sljit_emit_jump(compiler, (type))
-#define JUMPTO(type, label) \
- sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
-#define JUMPHERE(jump) \
- sljit_set_label((jump), sljit_emit_label(compiler))
-#define CMP(type, src1, src1w, src2, src2w) \
- sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
-#define CMPTO(type, src1, src1w, src2, src2w, label) \
- sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
-#define COND_VALUE(op, dst, dstw, type) \
- sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
-#define GET_LOCAL_BASE(dst, dstw, offset) \
- sljit_get_local_base(compiler, (dst), (dstw), (offset))
-
-static pcre_uchar* bracketend(pcre_uchar* cc)
-{
-SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
-do cc += GET(cc, 1); while (*cc == OP_ALT);
-SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
-cc += 1 + LINK_SIZE;
-return cc;
-}
-
-/* Functions whose might need modification for all new supported opcodes:
- next_opcode
- get_localspace
- set_localptrs
- get_framesize
- init_frame
- get_localsize
- copy_locals
- compile_trypath
- compile_backtrackpath
-*/
-
-static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
-{
-SLJIT_UNUSED_ARG(common);
-switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_DEF:
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- case OP_COMMIT:
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- case OP_SKIPZERO:
- return cc + 1;
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UTF
- if (common->utf) return NULL;
-#endif
- return cc + 1;
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- cc += 2;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- return cc;
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSUPTO:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSUPTOI:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSUPTO:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSUPTOI:
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- return cc;
-
- case OP_NOTPROP:
- case OP_PROP:
- return cc + 1 + 2;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- case OP_REF:
- case OP_REFI:
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_CLOSE:
- cc += 1 + IMM2_SIZE;
- return cc;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- return cc + 1 + 2 * IMM2_SIZE;
-
- case OP_CLASS:
- case OP_NCLASS:
- return cc + 1 + 32 / sizeof(pcre_uchar);
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- return cc + GET(cc, 1);
-#endif
-
- case OP_RECURSE:
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_REVERSE:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRA:
- case OP_BRAPOS:
- case OP_COND:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- return cc + 1 + LINK_SIZE;
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- return cc + 1 + LINK_SIZE + IMM2_SIZE;
-
- case OP_MARK:
- return cc + 1 + 2 + cc[1];
-
- default:
- return NULL;
- }
-}
-
-static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
-{
-int localspace = 0;
-pcre_uchar *alternative;
-/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_SET_SOM:
- common->has_set_som = TRUE;
- cc += 1;
- 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:
- case OP_SCOND:
- localspace += sizeof(sljit_w);
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- localspace += sizeof(sljit_w);
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- localspace += sizeof(sljit_w);
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_RECURSE:
- /* Set its value only once. */
- if (common->recursive_head == 0)
- {
- common->recursive_head = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_MARK:
- if (common->mark_ptr == 0)
- {
- common->mark_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- }
- cc += 1 + 2 + cc[1];
- break;
-
- default:
- cc = next_opcode(common, cc);
- if (cc == NULL)
- return -1;
- break;
- }
- }
-return localspace;
-}
-
-static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
-{
-pcre_uchar *cc = common->start;
-pcre_uchar *alternative;
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- common->localptrs[cc - common->start] = localptr;
- localptr += sizeof(sljit_w);
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- common->localptrs[cc - common->start] = localptr;
- localptr += sizeof(sljit_w);
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- {
- common->localptrs[cc - common->start] = localptr;
- localptr += sizeof(sljit_w);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
- }
-}
-
-/* Returns with -1 if no need for frame. */
-static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
-{
-pcre_uchar *ccend = bracketend(cc);
-int length = 0;
-BOOL possessive = FALSE;
-BOOL setsom_found = recursive;
-BOOL setmark_found = recursive;
-
-if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
- {
- length = 3;
- possessive = TRUE;
- }
-
-cc = next_opcode(common, cc);
-SLJIT_ASSERT(cc != NULL);
-while (cc < ccend)
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- if (!setsom_found)
- {
- length += 2;
- setsom_found = TRUE;
- }
- cc += 1;
- break;
-
- case OP_MARK:
- SLJIT_ASSERT(common->mark_ptr != 0);
- if (!setmark_found)
- {
- length += 2;
- setmark_found = TRUE;
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_RECURSE:
- if (common->has_set_som && !setsom_found)
- {
- length += 2;
- setsom_found = TRUE;
- }
- if (common->mark_ptr != 0 && !setmark_found)
- {
- length += 2;
- setmark_found = TRUE;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- length += 3;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
-
-/* Possessive quantifiers can use a special case. */
-if (SLJIT_UNLIKELY(possessive) && length == 3)
- return -1;
-
-if (length > 0)
- return length + 1;
-return -1;
-}
-
-static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
-{
-DEFINE_COMPILER;
-pcre_uchar *ccend = bracketend(cc);
-BOOL setsom_found = recursive;
-BOOL setmark_found = recursive;
-int offset;
-
-/* >= 1 + shortest item size (2) */
-SLJIT_UNUSED_ARG(stacktop);
-SLJIT_ASSERT(stackpos >= stacktop + 2);
-
-stackpos = STACK(stackpos);
-if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
- cc = next_opcode(common, cc);
-SLJIT_ASSERT(cc != NULL);
-while (cc < ccend)
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- if (!setsom_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos += (int)sizeof(sljit_w);
- setsom_found = TRUE;
- }
- cc += 1;
- break;
-
- case OP_MARK:
- 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);
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos += (int)sizeof(sljit_w);
- setmark_found = TRUE;
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_RECURSE:
- 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);
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos += (int)sizeof(sljit_w);
- setsom_found = TRUE;
- }
- 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);
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos += (int)sizeof(sljit_w);
- setmark_found = TRUE;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos += (int)sizeof(sljit_w);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
- stackpos += (int)sizeof(sljit_w);
-
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
-
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
-SLJIT_ASSERT(stackpos == STACK(stacktop));
-}
-
-static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
-{
-int localsize = 2;
-pcre_uchar *alternative;
-/* Calculate the sum of the local variables. */
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- localsize++;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- localsize++;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- localsize += 2;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- localsize++;
- cc += 1 + LINK_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
- }
-SLJIT_ASSERT(cc == ccend);
-return localsize;
-}
-
-static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
- BOOL save, int stackptr, int stacktop)
-{
-DEFINE_COMPILER;
-int srcw[2];
-int count;
-BOOL tmp1next = TRUE;
-BOOL tmp1empty = TRUE;
-BOOL tmp2empty = TRUE;
-pcre_uchar *alternative;
-enum {
- start,
- loop,
- end
-} status;
-
-status = save ? start : loop;
-stackptr = STACK(stackptr - 2);
-stacktop = STACK(stacktop - 1);
-
-if (!save)
- {
- stackptr += sizeof(sljit_w);
- if (stackptr < stacktop)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
- stackptr += sizeof(sljit_w);
- tmp1empty = FALSE;
- }
- if (stackptr < stacktop)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
- stackptr += sizeof(sljit_w);
- tmp2empty = FALSE;
- }
- /* The tmp1next must be TRUE in either way. */
- }
-
-while (status != end)
- {
- count = 0;
- switch(status)
- {
- case start:
- SLJIT_ASSERT(save && common->recursive_head != 0);
- count = 1;
- srcw[0] = common->recursive_head;
- status = loop;
- break;
-
- case loop:
- if (cc >= ccend)
- {
- status = end;
- break;
- }
-
- switch(*cc)
- {
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- count = 1;
- srcw[0] = PRIV_DATA(cc);
- SLJIT_ASSERT(srcw[0] != 0);
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- count = 1;
- srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- count = 2;
- srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
- srcw[0] = PRIV_DATA(cc);
- SLJIT_ASSERT(srcw[0] != 0);
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- {
- count = 1;
- srcw[0] = PRIV_DATA(cc);
- SLJIT_ASSERT(srcw[0] != 0);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
- break;
-
- case end:
- SLJIT_ASSERT_STOP();
- break;
- }
-
- while (count > 0)
- {
- count--;
- if (save)
- {
- if (tmp1next)
- {
- if (!tmp1empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
- stackptr += sizeof(sljit_w);
- }
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
- tmp1empty = FALSE;
- tmp1next = FALSE;
- }
- else
- {
- if (!tmp2empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
- stackptr += sizeof(sljit_w);
- }
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
- tmp2empty = FALSE;
- tmp1next = TRUE;
- }
- }
- else
- {
- if (tmp1next)
- {
- SLJIT_ASSERT(!tmp1empty);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
- tmp1empty = stackptr >= stacktop;
- if (!tmp1empty)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
- stackptr += sizeof(sljit_w);
- }
- tmp1next = FALSE;
- }
- else
- {
- SLJIT_ASSERT(!tmp2empty);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
- tmp2empty = stackptr >= stacktop;
- if (!tmp2empty)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
- stackptr += sizeof(sljit_w);
- }
- tmp1next = TRUE;
- }
- }
- }
- }
-
-if (save)
- {
- if (tmp1next)
- {
- if (!tmp1empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
- stackptr += sizeof(sljit_w);
- }
- if (!tmp2empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
- stackptr += sizeof(sljit_w);
- }
- }
- else
- {
- if (!tmp2empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
- stackptr += sizeof(sljit_w);
- }
- if (!tmp1empty)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
- stackptr += sizeof(sljit_w);
- }
- }
- }
-SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
-}
-
-static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
-{
-return (value & (value - 1)) == 0;
-}
-
-static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
-{
-while (list)
- {
- /* sljit_set_label is clever enough to do nothing
- if either the jump or the label is NULL */
- sljit_set_label(list->jump, label);
- list = list->next;
- }
-}
-
-static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
-{
-jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
-if (list_item)
- {
- list_item->next = *list;
- list_item->jump = jump;
- *list = list_item;
- }
-}
-
-static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
-{
-DEFINE_COMPILER;
-stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
-
-if (list_item)
- {
- list_item->type = type;
- list_item->data = data;
- list_item->start = start;
- list_item->leave = LABEL();
- list_item->next = common->stubs;
- common->stubs = list_item;
- }
-}
-
-static void flush_stubs(compiler_common *common)
-{
-DEFINE_COMPILER;
-stub_list* list_item = common->stubs;
-
-while (list_item)
- {
- JUMPHERE(list_item->start);
- switch(list_item->type)
- {
- case stack_alloc:
- add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
- break;
- }
- JUMPTO(SLJIT_JUMP, list_item->leave);
- list_item = list_item->next;
- }
-common->stubs = NULL;
-}
-
-static SLJIT_INLINE void decrease_call_count(compiler_common *common)
-{
-DEFINE_COMPILER;
-
-OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
-add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
-}
-
-static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
-{
-/* May destroy all locals and registers except TMP2. */
-DEFINE_COMPILER;
-
-OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
-#ifdef DESTROY_REGISTERS
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
-OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
-#endif
-add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
-}
-
-static SLJIT_INLINE void free_stack(compiler_common *common, int size)
-{
-DEFINE_COMPILER;
-OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
-}
-
-static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-int i;
-/* At this point we can freely use all temporary registers. */
-/* TMP1 returns with begin - 1. */
-OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
-if (length < 8)
- {
- for (i = 0; i < length; i++)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
- }
-else
- {
- GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
- loop = LABEL();
- OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_C_NOT_ZERO, loop);
- }
-}
-
-static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_jump *earlyexit;
-
-/* At this point we can freely use all registers. */
-OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
-
-OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
-OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
-OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
-OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
-GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
-/* Unlikely, but possible */
-earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
-loop = LABEL();
-OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
-OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
-/* Copy the integer value to the output buffer */
-#ifdef COMPILE_PCRE16
-OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
-#endif
-OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
-JUMPTO(SLJIT_C_NOT_ZERO, loop);
-JUMPHERE(earlyexit);
-
-/* Calculate the return value, which is the maximum ovector value. */
-if (topbracket > 1)
- {
- GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
-
- /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
- loop = LABEL();
- OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
- OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
- CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
- }
-else
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
-}
-
-static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
-{
-DEFINE_COMPILER;
-
-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));
-
-OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
-OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
-CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
-
-/* Store match begin and end. */
-OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
-OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
-OP1(SLJIT_MOV, SLJIT_TEMPORARY_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);
-#ifdef COMPILE_PCRE16
-OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
-#endif
-OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
-
-OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
-#ifdef COMPILE_PCRE16
-OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
-#endif
-OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
-
-JUMPTO(SLJIT_JUMP, leave);
-}
-
-static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
-{
-/* May destroy TMP1. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
- {
- /* The value of -1 must be kept for start_used_ptr! */
- OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
- /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
- is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
- jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
- {
- jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-}
-
-static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
-{
-/* Detects if the character has an othercase. */
-unsigned int c;
-
-#ifdef SUPPORT_UTF
-if (common->utf)
- {
- GETCHAR(c, cc);
- if (c > 127)
- {
-#ifdef SUPPORT_UCP
- return c != UCD_OTHERCASE(c);
-#else
- return FALSE;
-#endif
- }
-#ifndef COMPILE_PCRE8
- return common->fcc[c] != c;
-#endif
- }
-else
-#endif
- c = *cc;
-return MAX_255(c) ? common->fcc[c] != c : FALSE;
-}
-
-static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
-{
-/* Returns with the othercase. */
-#ifdef SUPPORT_UTF
-if (common->utf && c > 127)
- {
-#ifdef SUPPORT_UCP
- return UCD_OTHERCASE(c);
-#else
- return c;
-#endif
- }
-#endif
-return TABLE_GET(c, common->fcc, c);
-}
-
-static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
-{
-/* Detects if the character and its othercase has only 1 bit difference. */
-unsigned int c, oc, bit;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-int n;
-#endif
-
-#ifdef SUPPORT_UTF
-if (common->utf)
- {
- GETCHAR(c, cc);
- if (c <= 127)
- oc = common->fcc[c];
- else
- {
-#ifdef SUPPORT_UCP
- oc = UCD_OTHERCASE(c);
-#else
- oc = c;
-#endif
- }
- }
-else
- {
- c = *cc;
- oc = TABLE_GET(c, common->fcc, c);
- }
-#else
-c = *cc;
-oc = TABLE_GET(c, common->fcc, c);
-#endif
-
-SLJIT_ASSERT(c != oc);
-
-bit = c ^ oc;
-/* Optimized for English alphabet. */
-if (c <= 127 && bit == 0x20)
- return (0 << 8) | 0x20;
-
-/* Since c != oc, they must have at least 1 bit difference. */
-if (!ispowerof2(bit))
- return 0;
-
-#ifdef COMPILE_PCRE8
-
-#ifdef SUPPORT_UTF
-if (common->utf && c > 127)
- {
- n = GET_EXTRALEN(*cc);
- while ((bit & 0x3f) == 0)
- {
- n--;
- bit >>= 6;
- }
- return (n << 8) | bit;
- }
-#endif /* SUPPORT_UTF */
-return (0 << 8) | bit;
-
-#else /* COMPILE_PCRE8 */
-
-#ifdef COMPILE_PCRE16
-#ifdef SUPPORT_UTF
-if (common->utf && c > 65535)
- {
- if (bit >= (1 << 10))
- bit >>= 10;
- else
- return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
- }
-#endif /* SUPPORT_UTF */
-return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
-#endif /* COMPILE_PCRE16 */
-
-#endif /* COMPILE_PCRE8 */
-}
-
-static void check_partial(compiler_common *common, BOOL force)
-{
-/* Checks whether a partial matching is occured. Does not modify registers. */
-DEFINE_COMPILER;
-struct sljit_jump *jump = NULL;
-
-SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
-
-if (common->mode == JIT_COMPILE)
- return;
-
-if (!force)
- jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
-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);
-else
- {
- if (common->partialmatchlabel != NULL)
- JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
- }
-
-if (jump != NULL)
- JUMPHERE(jump);
-}
-
-static struct sljit_jump *check_str_end(compiler_common *common)
-{
-/* 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);
-
-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);
- }
-else
- {
- return_value = 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)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (common->mode == JIT_COMPILE)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- return;
- }
-
-/* Partial matching mode. */
-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);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- }
-else
- {
- if (common->partialmatchlabel != NULL)
- JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
- }
-JUMPHERE(jump);
-}
-
-static void read_char(compiler_common *common)
-{
-/* Reads the character into TMP1, updates STR_PTR.
-Does not check STR_END. TMP2 Destroyed. */
-DEFINE_COMPILER;
-#ifdef SUPPORT_UTF
-struct sljit_jump *jump;
-#endif
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#ifdef SUPPORT_UTF
-if (common->utf)
- {
-#ifdef COMPILE_PCRE8
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
-#else
-#ifdef COMPILE_PCRE16
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
-#endif
-#endif /* COMPILE_PCRE8 */
- add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
- JUMPHERE(jump);
- }
-#endif
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-}
-
-static void peek_char(compiler_common *common)
-{
-/* Reads the character into TMP1, keeps STR_PTR.
-Does not check STR_END. TMP2 Destroyed. */
-DEFINE_COMPILER;
-#ifdef SUPPORT_UTF
-struct sljit_jump *jump;
-#endif
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#ifdef SUPPORT_UTF
-if (common->utf)
- {
-#ifdef COMPILE_PCRE8
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
-#else
-#ifdef COMPILE_PCRE16
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
-#endif
-#endif /* COMPILE_PCRE8 */
- add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- JUMPHERE(jump);
- }
-#endif
-}
-
-static void read_char8_type(compiler_common *common)
-{
-/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
-DEFINE_COMPILER;
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
-struct sljit_jump *jump;
-#endif
-
-#ifdef SUPPORT_UTF
-if (common->utf)
- {
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#ifdef COMPILE_PCRE8
- /* This can be an extra read in some situations, but hopefully
- it is needed in most cases. */
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
- add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
- JUMPHERE(jump);
-#else
-#ifdef COMPILE_PCRE16
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- JUMPHERE(jump);
- /* Skip low surrogate if necessary. */
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-#endif
-#endif /* COMPILE_PCRE8 */
- return;
- }
-#endif
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#ifdef COMPILE_PCRE16
-/* The ctypes array contains only 256 values. */
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
-#endif
-OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-#ifdef COMPILE_PCRE16
-JUMPHERE(jump);
-#endif
-}
-
-static void skip_char_back(compiler_common *common)
-{
-/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
-DEFINE_COMPILER;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-struct sljit_label *label;
-
-if (common->utf)
- {
- label = LABEL();
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
- CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
- return;
- }
-#endif
-#if defined SUPPORT_UTF && defined COMPILE_PCRE16
-if (common->utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- /* Skip low surrogate if necessary. */
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- return;
- }
-#endif
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-}
-
-static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
-{
-/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
-DEFINE_COMPILER;
-
-if (nltype == NLTYPE_ANY)
- {
- add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
- }
-else if (nltype == NLTYPE_ANYCRLF)
- {
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
- }
-else
- {
- SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
- add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
- }
-}
-
-#ifdef SUPPORT_UTF
-
-#ifdef COMPILE_PCRE8
-static void do_utfreadchar(compiler_common *common)
-{
-/* Fast decoding a UTF-8 character. TMP1 contains the first byte
-of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-/* Searching for the first zero. */
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
-jump = JUMP(SLJIT_C_NOT_ZERO);
-/* Two byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
-
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
-jump = JUMP(SLJIT_C_NOT_ZERO);
-/* Three byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
-
-/* Four byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-static void do_utfreadtype8(compiler_common *common)
-{
-/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
-of the character (>= 0xc0). Return value in TMP1. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_jump *compare;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
-jump = JUMP(SLJIT_C_NOT_ZERO);
-/* Two byte sequence. */
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
-compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
-OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-
-JUMPHERE(compare);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
-
-/* We only have types for characters less than 256. */
-OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-#else /* COMPILE_PCRE8 */
-
-#ifdef COMPILE_PCRE16
-static void do_utfreadchar(compiler_common *common)
-{
-/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
-of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
-/* Do nothing, only return. */
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-/* Combine two 16 bit characters. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-#endif /* COMPILE_PCRE16 */
-
-#endif /* COMPILE_PCRE8 */
-
-#endif /* SUPPORT_UTF */
-
-#ifdef SUPPORT_UCP
-
-static sljit_w SLJIT_CALL getunichartype(sljit_w c)
-{
- return (sljit_w)(unsigned int)UCD_CHARTYPE((unsigned int)c);
-}
-
-static sljit_w SLJIT_CALL getunicharscript(sljit_w c)
-{
- return (sljit_w)(unsigned int)UCD_SCRIPT((unsigned int)c);
-}
-
-static void do_getunichartype(compiler_common *common)
-{
-/* Character comes in TMP1. Returns chartype in TMP1 */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-/* Save registers */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
-sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(getunichartype));
-/* Restore registers */
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-static void do_getunichartype_2(compiler_common *common)
-{
-/* Character comes in TMP1. Returns chartype in TMP1 */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-/* Save registers */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STACK_TOP, 0);
-sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(getunichartype));
-/* Restore registers */
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-static void do_getunicharscript(compiler_common *common)
-{
-/* Character comes in TMP1. Returns chartype in TMP1 */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-/* Save registers */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
-sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(getunicharscript));
-/* Restore registers */
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-#endif
-
-static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
-{
-DEFINE_COMPILER;
-struct sljit_label *mainloop;
-struct sljit_label *newlinelabel = NULL;
-struct sljit_jump *start;
-struct sljit_jump *end = NULL;
-struct sljit_jump *nl = NULL;
-#ifdef SUPPORT_UTF
-struct sljit_jump *singlechar;
-#endif
-jump_list *newline = NULL;
-BOOL newlinecheck = FALSE;
-BOOL readuchar = FALSE;
-
-if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
- common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
- newlinecheck = TRUE;
-
-if (firstline)
- {
- /* Search for the end of the first line. */
- SLJIT_ASSERT(common->first_line_end != 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
-
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- mainloop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
- CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
- OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
- else
- {
- end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- mainloop = LABEL();
- /* Continual stores does not cause data dependency. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
- read_char(common);
- check_newlinechar(common, common->nltype, &newline, TRUE);
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
- set_jumps(newline, LABEL());
- }
-
- JUMPHERE(end);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
- }
-
-start = JUMP(SLJIT_JUMP);
-
-if (newlinecheck)
- {
- newlinelabel = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
-#ifdef COMPILE_PCRE16
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
-#endif
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- nl = JUMP(SLJIT_JUMP);
- }
-
-mainloop = LABEL();
-
-/* Increasing the STR_PTR here requires one less jump in the most common case. */
-#ifdef SUPPORT_UTF
-if (common->utf) readuchar = TRUE;
-#endif
-if (newlinecheck) readuchar = TRUE;
-
-if (readuchar)
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-
-if (newlinecheck)
- CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (common->utf)
- {
- singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(singlechar);
- }
-#endif
-#if defined SUPPORT_UTF && defined COMPILE_PCRE16
-if (common->utf)
- {
- singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(singlechar);
- }
-#endif
-JUMPHERE(start);
-
-if (newlinecheck)
- {
- JUMPHERE(end);
- JUMPHERE(nl);
- }
-
-return mainloop;
-}
-
-static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
-{
-DEFINE_COMPILER;
-struct sljit_label *start;
-struct sljit_jump *leave;
-struct sljit_jump *found;
-pcre_uchar oc, bit;
-
-if (firstline)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
- }
-
-start = LABEL();
-leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-
-oc = first_char;
-if (caseless)
- {
- oc = TABLE_GET(first_char, common->fcc, first_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (first_char > 127 && common->utf)
- oc = UCD_OTHERCASE(first_char);
-#endif
- }
-if (first_char == oc)
- found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
-else
- {
- bit = first_char ^ oc;
- if (ispowerof2(bit))
- {
- OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
- found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
- }
- else
- {
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- found = JUMP(SLJIT_C_NOT_ZERO);
- }
- }
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (common->utf)
- {
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- }
-#endif
-#if defined SUPPORT_UTF && defined COMPILE_PCRE16
-if (common->utf)
- {
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- }
-#endif
-JUMPTO(SLJIT_JUMP, start);
-JUMPHERE(found);
-JUMPHERE(leave);
-
-if (firstline)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
-}
-
-static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_jump *lastchar;
-struct sljit_jump *firstchar;
-struct sljit_jump *leave;
-struct sljit_jump *foundcr = NULL;
-struct sljit_jump *notfoundnl;
-jump_list *newline = NULL;
-
-if (firstline)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
- }
-
-if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
-#ifdef COMPILE_PCRE16
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
-#endif
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
- loop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
- CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
-
- JUMPHERE(leave);
- JUMPHERE(firstchar);
- JUMPHERE(lastchar);
-
- if (firstline)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
- return;
- }
-
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-skip_char_back(common);
-
-loop = LABEL();
-read_char(common);
-lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
-check_newlinechar(common, common->nltype, &newline, FALSE);
-set_jumps(newline, loop);
-
-if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- {
- leave = JUMP(SLJIT_JUMP);
- JUMPHERE(foundcr);
- notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
-#ifdef COMPILE_PCRE16
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
-#endif
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(notfoundnl);
- JUMPHERE(leave);
- }
-JUMPHERE(lastchar);
-JUMPHERE(firstchar);
-
-if (firstline)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
-}
-
-static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
-{
-DEFINE_COMPILER;
-struct sljit_label *start;
-struct sljit_jump *leave;
-struct sljit_jump *found;
-#ifndef COMPILE_PCRE8
-struct sljit_jump *jump;
-#endif
-
-if (firstline)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
- }
-
-start = LABEL();
-leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#ifdef SUPPORT_UTF
-if (common->utf)
- OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-#endif
-#ifndef COMPILE_PCRE8
-jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
-JUMPHERE(jump);
-#endif
-OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
-OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
-OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
-found = JUMP(SLJIT_C_NOT_ZERO);
-
-#ifdef SUPPORT_UTF
-if (common->utf)
- OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-#endif
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (common->utf)
- {
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- }
-#endif
-#if defined SUPPORT_UTF && defined COMPILE_PCRE16
-if (common->utf)
- {
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- }
-#endif
-JUMPTO(SLJIT_JUMP, start);
-JUMPHERE(found);
-JUMPHERE(leave);
-
-if (firstline)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
-}
-
-static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_jump *toolong;
-struct sljit_jump *alreadyfound;
-struct sljit_jump *found;
-struct sljit_jump *foundoc = NULL;
-struct sljit_jump *notfound;
-pcre_uchar oc, bit;
-
-SLJIT_ASSERT(common->req_char_ptr != 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
-OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
-toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
-alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
-
-if (has_firstchar)
- OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-else
- OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
-
-loop = LABEL();
-notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
-oc = req_char;
-if (caseless)
- {
- oc = TABLE_GET(req_char, common->fcc, req_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (req_char > 127 && common->utf)
- oc = UCD_OTHERCASE(req_char);
-#endif
- }
-if (req_char == oc)
- found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
-else
- {
- bit = req_char ^ oc;
- if (ispowerof2(bit))
- {
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
- found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
- }
- else
- {
- found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
- foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
- }
- }
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_JUMP, loop);
-
-JUMPHERE(found);
-if (foundoc)
- JUMPHERE(foundoc);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
-JUMPHERE(alreadyfound);
-JUMPHERE(toolong);
-return notfound;
-}
-
-static void do_revertframes(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *mainloop;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
-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_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
-JUMPTO(SLJIT_JUMP, mainloop);
-
-JUMPHERE(jump);
-jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
-/* End of dropping frames. */
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
-/* Set string begin. */
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
-JUMPTO(SLJIT_JUMP, mainloop);
-
-JUMPHERE(jump);
-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_w));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
- JUMPTO(SLJIT_JUMP, mainloop);
-
- JUMPHERE(jump);
- }
-
-/* Unknown command. */
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
-JUMPTO(SLJIT_JUMP, mainloop);
-}
-
-static void check_wordboundary(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *skipread;
-#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
-struct sljit_jump *jump;
-#endif
-
-SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
-
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-/* Get type of the previous char, and put it to LOCALS1. */
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
-skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
-skip_char_back(common);
-check_start_used_ptr(common);
-read_char(common);
-
-/* Testing char type. */
-#ifdef SUPPORT_UCP
-if (common->use_ucp)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
- jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
- add_jump(compiler, &common->getunichartype_2, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
- JUMPHERE(jump);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
- }
-else
-#endif
- {
-#ifndef COMPILE_PCRE8
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UTF
- /* Here LOCALS1 has already been zeroed. */
- jump = NULL;
- if (common->utf)
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif /* COMPILE_PCRE8 */
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
-#ifndef COMPILE_PCRE8
- JUMPHERE(jump);
-#elif defined SUPPORT_UTF
- if (jump != NULL)
- JUMPHERE(jump);
-#endif /* COMPILE_PCRE8 */
- }
-JUMPHERE(skipread);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
-skipread = check_str_end(common);
-peek_char(common);
-
-/* Testing char type. This is a code duplication. */
-#ifdef SUPPORT_UCP
-if (common->use_ucp)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
- jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
- add_jump(compiler, &common->getunichartype_2, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
- JUMPHERE(jump);
- }
-else
-#endif
- {
-#ifndef COMPILE_PCRE8
- /* TMP2 may be destroyed by peek_char. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UTF
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
- jump = NULL;
- if (common->utf)
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif
- OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
- OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
-#ifndef COMPILE_PCRE8
- JUMPHERE(jump);
-#elif defined SUPPORT_UTF
- if (jump != NULL)
- JUMPHERE(jump);
-#endif /* COMPILE_PCRE8 */
- }
-JUMPHERE(skipread);
-
-OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
-sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-}
-
-static void check_anynewline(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
-#ifdef COMPILE_PCRE8
-if (common->utf)
- {
-#endif
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
-#ifdef COMPILE_PCRE8
- }
-#endif
-#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
-COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-static void check_hspace(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
-COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
-COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
-#ifdef COMPILE_PCRE8
-if (common->utf)
- {
-#endif
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
-#ifdef COMPILE_PCRE8
- }
-#endif
-#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
-COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
-
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-static void check_vspace(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
-#ifdef COMPILE_PCRE8
-if (common->utf)
- {
-#endif
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
-#ifdef COMPILE_PCRE8
- }
-#endif
-#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
-COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
-
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-#define CHAR1 STR_END
-#define CHAR2 STACK_TOP
-
-static void do_casefulcmp(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *label;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_C_NOT_ZERO, label);
-
-JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-#define LCC_TABLE STACK_LIMIT
-
-static void do_caselesscmp(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *label;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
-OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-#ifndef COMPILE_PCRE8
-jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
-#endif
-OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
-#ifndef COMPILE_PCRE8
-JUMPHERE(jump);
-jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
-#endif
-OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
-#ifndef COMPILE_PCRE8
-JUMPHERE(jump);
-#endif
-jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_C_NOT_ZERO, label);
-
-JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-#undef LCC_TABLE
-#undef CHAR1
-#undef CHAR2
-
-#if defined SUPPORT_UTF && defined SUPPORT_UCP
-
-static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
-{
-/* This function would be ineffective to do in JIT level. */
-int c1, c2;
-const pcre_uchar *src2 = args->uchar_ptr;
-const pcre_uchar *end2 = args->end;
-
-while (src1 < end1)
- {
- if (src2 >= end2)
- return (pcre_uchar*)1;
- GETCHARINC(c1, src1);
- GETCHARINC(c2, src2);
- if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
- }
-return src2;
-}
-
-#endif /* SUPPORT_UTF && SUPPORT_UCP */
-
-static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
- compare_context* context, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-unsigned int othercasebit = 0;
-pcre_uchar *othercasechar = NULL;
-#ifdef SUPPORT_UTF
-int utflength;
-#endif
-
-if (caseless && char_has_othercase(common, cc))
- {
- othercasebit = char_get_othercase_bit(common, cc);
- SLJIT_ASSERT(othercasebit);
- /* Extracting bit difference info. */
-#ifdef COMPILE_PCRE8
- othercasechar = cc + (othercasebit >> 8);
- othercasebit &= 0xff;
-#else
-#ifdef COMPILE_PCRE16
- othercasechar = cc + (othercasebit >> 9);
- if ((othercasebit & 0x100) != 0)
- othercasebit = (othercasebit & 0xff) << 8;
- else
- othercasebit &= 0xff;
-#endif
-#endif
- }
-
-if (context->sourcereg == -1)
- {
-#ifdef COMPILE_PCRE8
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- if (context->length >= 4)
- OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else if (context->length >= 2)
- OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else
-#endif
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#else
-#ifdef COMPILE_PCRE16
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- if (context->length >= 4)
- OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else
-#endif
- OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif
-#endif /* COMPILE_PCRE8 */
- context->sourcereg = TMP2;
- }
-
-#ifdef SUPPORT_UTF
-utflength = 1;
-if (common->utf && HAS_EXTRALEN(*cc))
- utflength += GET_EXTRALEN(*cc);
-
-do
- {
-#endif
-
- context->length -= IN_UCHARS(1);
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
-
- /* Unaligned read is supported. */
- if (othercasebit != 0 && othercasechar == cc)
- {
- context->c.asuchars[context->ucharptr] = *cc | othercasebit;
- context->oc.asuchars[context->ucharptr] = othercasebit;
- }
- else
- {
- context->c.asuchars[context->ucharptr] = *cc;
- context->oc.asuchars[context->ucharptr] = 0;
- }
- context->ucharptr++;
-
-#ifdef COMPILE_PCRE8
- if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
-#else
- if (context->ucharptr >= 2 || context->length == 0)
-#endif
- {
- if (context->length >= 4)
- OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#ifdef COMPILE_PCRE8
- else if (context->length >= 2)
- OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else if (context->length >= 1)
- OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#else
- else if (context->length >= 2)
- OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif
- context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
-
- switch(context->ucharptr)
- {
- case 4 / sizeof(pcre_uchar):
- if (context->oc.asint != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
- break;
-
- case 2 / sizeof(pcre_uchar):
- if (context->oc.asushort != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
- break;
-
-#ifdef COMPILE_PCRE8
- case 1:
- if (context->oc.asbyte != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
- break;
-#endif
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
- context->ucharptr = 0;
- }
-
-#else
-
- /* Unaligned read is unsupported. */
-#ifdef COMPILE_PCRE8
- if (context->length > 0)
- OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#else
- if (context->length > 0)
- OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif
- context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
-
- if (othercasebit != 0 && othercasechar == cc)
- {
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
-
-#endif
-
- cc++;
-#ifdef SUPPORT_UTF
- utflength--;
- }
-while (utflength > 0);
-#endif
-
-return cc;
-}
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
-
-#define SET_TYPE_OFFSET(value) \
- if ((value) != typeoffset) \
- { \
- if ((value) > typeoffset) \
- OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
- else \
- OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
- } \
- typeoffset = (value);
-
-#define SET_CHAR_OFFSET(value) \
- if ((value) != charoffset) \
- { \
- if ((value) > charoffset) \
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
- else \
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
- } \
- charoffset = (value);
-
-static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-jump_list *found = NULL;
-jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
-unsigned int c;
-int compares;
-struct sljit_jump *jump = NULL;
-pcre_uchar *ccbegin;
-#ifdef SUPPORT_UCP
-BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
-BOOL charsaved = FALSE;
-int typereg = TMP1, scriptreg = TMP1;
-unsigned int typeoffset;
-#endif
-int invertcmp, numberofcmps;
-unsigned int charoffset;
-
-/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
-detect_partial_match(common, backtracks);
-read_char(common);
-
-if ((*cc++ & XCL_MAP) != 0)
- {
- OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-#ifndef COMPILE_PCRE8
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UTF
- if (common->utf)
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif
-
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
- add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
-
-#ifndef COMPILE_PCRE8
- JUMPHERE(jump);
-#elif defined SUPPORT_UTF
- if (common->utf)
- JUMPHERE(jump);
-#endif
- OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-#ifdef SUPPORT_UCP
- charsaved = TRUE;
-#endif
- cc += 32 / sizeof(pcre_uchar);
- }
-
-/* Scanning the necessary info. */
-ccbegin = cc;
-compares = 0;
-while (*cc != XCL_END)
- {
- compares++;
- if (*cc == XCL_SINGLE)
- {
- cc += 2;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
-#ifdef SUPPORT_UCP
- needschar = TRUE;
-#endif
- }
- else if (*cc == XCL_RANGE)
- {
- cc += 2;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- cc++;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
-#ifdef SUPPORT_UCP
- needschar = TRUE;
-#endif
- }
-#ifdef SUPPORT_UCP
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- switch(*cc)
- {
- case PT_ANY:
- break;
-
- case PT_LAMP:
- case PT_GC:
- case PT_PC:
- case PT_ALNUM:
- needstype = TRUE;
- break;
-
- case PT_SC:
- needsscript = TRUE;
- break;
-
- case PT_SPACE:
- case PT_PXSPACE:
- case PT_WORD:
- needstype = TRUE;
- needschar = TRUE;
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
- cc += 2;
- }
-#endif
- }
-
-#ifdef SUPPORT_UCP
-/* Simple register allocation. TMP1 is preferred if possible. */
-if (needstype || needsscript)
- {
- if ((needschar || needsscript) && !charsaved)
- OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-
- /* Needed to save important temporary registers. */
- SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 &&
- STACK_TOP == SLJIT_TEMPORARY_REG2 &&
- TMP2 == SLJIT_TEMPORARY_REG3);
-
- if (needschar)
- {
- if (needstype)
- typereg = RETURN_ADDR;
- if (needsscript)
- scriptreg = TMP3;
- }
- else if (needstype && needsscript)
- scriptreg = TMP3;
- /* In all other cases only one of them was specified, and that can goes to TMP1. */
-
- if (needstype)
- {
- add_jump(compiler, &common->getunichartype, JUMP(SLJIT_FAST_CALL));
- if (typereg != TMP1)
- OP1(SLJIT_MOV, typereg, 0, TMP1, 0);
- }
-
- if (needsscript)
- {
- /* Get the char again */
- if (needstype)
- OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-
- add_jump(compiler, &common->getunicharscript, JUMP(SLJIT_FAST_CALL));
- if (scriptreg != TMP1)
- OP1(SLJIT_MOV, scriptreg, 0, TMP1, 0);
- }
-
- if (needschar)
- OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
- }
-#endif
-
-/* Generating code. */
-cc = ccbegin;
-charoffset = 0;
-numberofcmps = 0;
-#ifdef SUPPORT_UCP
-typeoffset = 0;
-#endif
-
-while (*cc != XCL_END)
- {
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
- jump = NULL;
-
- if (*cc == XCL_SINGLE)
- {
- cc ++;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
-
- if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
- {
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
- COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- numberofcmps++;
- }
- else if (numberofcmps > 0)
- {
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
- numberofcmps = 0;
- }
- else
- {
- jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
- numberofcmps = 0;
- }
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
- SET_CHAR_OFFSET(c);
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
- if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
- {
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
- COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
- numberofcmps++;
- }
- else if (numberofcmps > 0)
- {
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
- jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
- numberofcmps = 0;
- }
- else
- {
- jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
- numberofcmps = 0;
- }
- }
-#ifdef SUPPORT_UCP
- else
- {
- if (*cc == XCL_NOTPROP)
- invertcmp ^= 0x1;
- cc++;
- switch(*cc)
- {
- case PT_ANY:
- if (list != backtracks)
- {
- if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
- continue;
- }
- else if (cc[-1] == XCL_NOTPROP)
- continue;
- jump = JUMP(SLJIT_JUMP);
- break;
-
- case PT_LAMP:
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
- COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_GC:
- c = PRIV(ucp_typerange)[(int)cc[1] * 2];
- SET_TYPE_OFFSET(c);
- jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
- break;
-
- case PT_PC:
- jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
- break;
-
- case PT_SC:
- jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
- break;
-
- case PT_SPACE:
- case PT_PXSPACE:
- if (*cc == PT_SPACE)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
- }
- SET_CHAR_OFFSET(9);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
- if (*cc == PT_SPACE)
- JUMPHERE(jump);
-
- SET_TYPE_OFFSET(ucp_Zl);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
- jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_WORD:
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- /* ... fall through */
-
- case PT_ALNUM:
- SET_TYPE_OFFSET(ucp_Ll);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
- SET_TYPE_OFFSET(ucp_Nd);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
- jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
- break;
- }
- cc += 2;
- }
-#endif
-
- if (jump != NULL)
- add_jump(compiler, compares > 0 ? list : backtracks, jump);
- }
-
-if (found != NULL)
- set_jumps(found, LABEL());
-}
-
-#undef SET_TYPE_OFFSET
-#undef SET_CHAR_OFFSET
-
-#endif
-
-static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-int length;
-unsigned int c, oc, bit;
-compare_context context;
-struct sljit_jump *jump[4];
-#ifdef SUPPORT_UTF
-struct sljit_label *label;
-#ifdef SUPPORT_UCP
-pcre_uchar propdata[5];
-#endif
-#endif
-
-switch(type)
- {
- case OP_SOD:
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
- return cc;
-
- case OP_SOM:
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
- return cc;
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
- return cc;
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- detect_partial_match(common, backtracks);
- read_char8_type(common);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
- add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
- return cc;
-
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- detect_partial_match(common, backtracks);
- read_char8_type(common);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
- add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
- return cc;
-
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- detect_partial_match(common, backtracks);
- read_char8_type(common);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
- add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
- return cc;
-
- case OP_ANY:
- detect_partial_match(common, backtracks);
- read_char(common);
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
- if (common->mode != JIT_PARTIAL_HARD_COMPILE)
- jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- else
- jump[1] = check_str_end(common);
-
- 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]);
- JUMPHERE(jump[0]);
- }
- else
- check_newlinechar(common, common->nltype, backtracks, TRUE);
- return cc;
-
- case OP_ALLANY:
- detect_partial_match(common, backtracks);
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#ifdef COMPILE_PCRE8
- jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-#else /* COMPILE_PCRE8 */
-#ifdef COMPILE_PCRE16
- jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-#endif /* COMPILE_PCRE16 */
-#endif /* COMPILE_PCRE8 */
- JUMPHERE(jump[0]);
- return cc;
- }
-#endif
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- return cc;
-
- case OP_ANYBYTE:
- detect_partial_match(common, backtracks);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- return cc;
-
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- case OP_NOTPROP:
- case OP_PROP:
- propdata[0] = 0;
- propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
- propdata[2] = cc[0];
- propdata[3] = cc[1];
- propdata[4] = XCL_END;
- compile_xclass_trypath(common, propdata, backtracks);
- return cc + 2;
-#endif
-#endif
-
- case OP_ANYNL:
- detect_partial_match(common, backtracks);
- 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. */
- if (common->mode != JIT_PARTIAL_HARD_COMPILE)
- jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- else
- jump[1] = check_str_end(common);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump[3] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[0]);
- check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
- JUMPHERE(jump[1]);
- JUMPHERE(jump[2]);
- JUMPHERE(jump[3]);
- return cc;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- detect_partial_match(common, backtracks);
- read_char(common);
- add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
- return cc;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- detect_partial_match(common, backtracks);
- read_char(common);
- add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
- return cc;
-
-#ifdef SUPPORT_UCP
- case OP_EXTUNI:
- detect_partial_match(common, backtracks);
- read_char(common);
- add_jump(compiler, &common->getunichartype, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
-
- label = LABEL();
- jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
- read_char(common);
- add_jump(compiler, &common->getunichartype, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
- CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
-
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- JUMPHERE(jump[0]);
- if (common->mode == JIT_PARTIAL_HARD_COMPILE)
- {
- jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
- /* Since we successfully read a char above, partial matching must occure. */
- check_partial(common, TRUE);
- JUMPHERE(jump[0]);
- }
- return cc;
-#endif
-
- case OP_EODN:
- /* Requires rather complex checks. */
- jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (common->mode == JIT_COMPILE)
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
- else
- {
- jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
- add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
- check_partial(common, TRUE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(jump[1]);
- }
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else if (common->nltype == NLTYPE_FIXED)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
- }
- else
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
- jump[2] = JUMP(SLJIT_C_GREATER);
- add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
- /* Equal. */
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
-
- JUMPHERE(jump[1]);
- if (common->nltype == NLTYPE_ANYCRLF)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
- }
- else
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
- read_char(common);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
- add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
- }
- JUMPHERE(jump[2]);
- JUMPHERE(jump[3]);
- }
- JUMPHERE(jump[0]);
- check_partial(common, FALSE);
- return cc;
-
- case OP_EOD:
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
- check_partial(common, FALSE);
- return cc;
-
- case OP_CIRC:
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
- OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- return cc;
-
- case OP_CIRCM:
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
- jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
- OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- jump[0] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[1]);
-
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else
- {
- skip_char_back(common);
- read_char(common);
- check_newlinechar(common, common->nltype, backtracks, FALSE);
- }
- JUMPHERE(jump[0]);
- return cc;
-
- case OP_DOLL:
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
-
- if (!common->endonly)
- compile_char1_trypath(common, OP_EODN, cc, backtracks);
- else
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
- check_partial(common, FALSE);
- }
- return cc;
-
- case OP_DOLLM:
- jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- check_partial(common, FALSE);
- jump[0] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[1]);
-
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (common->mode == JIT_COMPILE)
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
- else
- {
- jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
- /* STR_PTR = STR_END - IN_UCHARS(1) */
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- check_partial(common, TRUE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(jump[1]);
- }
-
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else
- {
- peek_char(common);
- check_newlinechar(common, common->nltype, backtracks, FALSE);
- }
- JUMPHERE(jump[0]);
- return cc;
-
- case OP_CHAR:
- case OP_CHARI:
- length = 1;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
-#endif
- if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
- {
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
-
- context.length = IN_UCHARS(length);
- context.sourcereg = -1;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- context.ucharptr = 0;
-#endif
- return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
- }
- detect_partial_match(common, backtracks);
- read_char(common);
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHAR(c, cc);
- }
- else
-#endif
- c = *cc;
- if (type == OP_CHAR || !char_has_othercase(common, cc))
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
- return cc + length;
- }
- oc = char_othercase(common, c);
- bit = c ^ oc;
- if (ispowerof2(bit))
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
- return cc + length;
- }
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
- return cc + length;
-
- case OP_NOT:
- case OP_NOTI:
- detect_partial_match(common, backtracks);
- length = 1;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
-#ifdef COMPILE_PCRE8
- c = *cc;
- if (c < 128)
- {
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- if (type == OP_NOT || !char_has_othercase(common, cc))
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
- else
- {
- /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
- OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
- }
- /* Skip the variable-length character. */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(jump[0]);
- return cc + 1;
- }
- else
-#endif /* COMPILE_PCRE8 */
- {
- GETCHARLEN(c, cc, length);
- read_char(common);
- }
- }
- else
-#endif /* SUPPORT_UTF */
- {
- read_char(common);
- c = *cc;
- }
-
- if (type == OP_NOT || !char_has_othercase(common, cc))
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
- else
- {
- oc = char_othercase(common, c);
- bit = c ^ oc;
- if (ispowerof2(bit))
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
- }
- else
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
- }
- }
- return cc + length;
-
- case OP_CLASS:
- case OP_NCLASS:
- detect_partial_match(common, backtracks);
- read_char(common);
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- jump[0] = NULL;
-#ifdef COMPILE_PCRE8
- /* This check only affects 8 bit mode. In other modes, we
- always need to compare the value with 255. */
- if (common->utf)
-#endif /* COMPILE_PCRE8 */
- {
- jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
- if (type == OP_CLASS)
- {
- add_jump(compiler, backtracks, jump[0]);
- jump[0] = NULL;
- }
- }
-#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
- add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- if (jump[0] != NULL)
- JUMPHERE(jump[0]);
-#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
- return cc + 32 / sizeof(pcre_uchar);
-
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
- case OP_XCLASS:
- compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
- return cc + GET(cc, 0) - 1;
-#endif
-
- case OP_REVERSE:
- length = GET(cc, 0);
- if (length == 0)
- return cc + LINK_SIZE;
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
- label = LABEL();
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
- skip_char_back(common);
- OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_C_NOT_ZERO, label);
- }
- else
-#endif
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
- }
- check_start_used_ptr(common);
- return cc + LINK_SIZE;
- }
-SLJIT_ASSERT_STOP();
-return cc;
-}
-
-static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
-{
-/* This function consumes at least one input character. */
-/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
-DEFINE_COMPILER;
-pcre_uchar *ccbegin = cc;
-compare_context context;
-int size;
-
-context.length = 0;
-do
- {
- if (cc >= ccend)
- break;
-
- if (*cc == OP_CHAR)
- {
- size = 1;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[1]))
- size += GET_EXTRALEN(cc[1]);
-#endif
- }
- else if (*cc == OP_CHARI)
- {
- size = 1;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
- size = 0;
- else if (HAS_EXTRALEN(cc[1]))
- size += GET_EXTRALEN(cc[1]);
- }
- else
-#endif
- if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
- size = 0;
- }
- else
- size = 0;
-
- cc += 1 + size;
- context.length += IN_UCHARS(size);
- }
-while (size > 0 && context.length <= 128);
-
-cc = ccbegin;
-if (context.length > 0)
- {
- /* We have a fixed-length byte sequence. */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
- add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
-
- context.sourcereg = -1;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- context.ucharptr = 0;
-#endif
- do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
- return cc;
- }
-
-/* A non-fixed length character will be checked if length == 0. */
-return compile_char1_trypath(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));
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
- return JUMP(SLJIT_C_NOT_ZERO);
- }
- add_jump(compiler, 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_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
-static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
-
-#define PUSH_BACKTRACK(size, ccstart, error) \
- do \
- { \
- backtrack = sljit_alloc_memory(compiler, (size)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return error; \
- memset(backtrack, 0, size); \
- backtrack->prev = parent->top; \
- backtrack->cc = (ccstart); \
- parent->top = backtrack; \
- } \
- while (0)
-
-#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
- do \
- { \
- backtrack = sljit_alloc_memory(compiler, (size)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return; \
- memset(backtrack, 0, size); \
- backtrack->prev = parent->top; \
- backtrack->cc = (ccstart); \
- parent->top = backtrack; \
- } \
- while (0)
-
-#define BACKTRACK_AS(type) ((type *)backtrack)
-
-static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
-{
-DEFINE_COMPILER;
-int offset = GET2(cc, 1) << 1;
-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 defined SUPPORT_UTF && defined SUPPORT_UCP
-if (common->utf && *cc == OP_REFI)
- {
- SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- if (withchecks)
- jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
-
- /* Needed to save important temporary registers. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
- sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
- if (common->mode == JIT_COMPILE)
- add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
- else
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
- nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
- check_partial(common, FALSE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(nopartial);
- }
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
- }
-else
-#endif /* SUPPORT_UTF && SUPPORT_UCP */
- {
- OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
- if (withchecks)
- jump = JUMP(SLJIT_C_ZERO);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
- if (common->mode == JIT_COMPILE)
- add_jump(compiler, backtracks, partial);
-
- add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
-
- if (common->mode != JIT_COMPILE)
- {
- nopartial = JUMP(SLJIT_JUMP);
- JUMPHERE(partial);
- /* TMP2 -= STR_END - STR_PTR */
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
- partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
- add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- JUMPHERE(partial);
- check_partial(common, FALSE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(nopartial);
- }
- }
-
-if (jump != NULL)
- {
- if (emptyfail)
- add_jump(compiler, backtracks, jump);
- else
- JUMPHERE(jump);
- }
-return cc + 1 + IMM2_SIZE;
-}
-
-static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-pcre_uchar type;
-struct sljit_label *label;
-struct sljit_jump *zerolength;
-struct sljit_jump *jump = NULL;
-pcre_uchar *ccbegin = cc;
-int min = 0, max = 0;
-BOOL minimize;
-
-PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
-
-type = cc[1 + IMM2_SIZE];
-minimize = (type & 0x1) != 0;
-switch(type)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- min = 0;
- max = 0;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- min = 1;
- max = 0;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- min = 0;
- max = 1;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(cc, 1 + IMM2_SIZE + 1);
- max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
- cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
- break;
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
-
-if (!minimize)
- {
- if (min == 0)
- {
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
- /* Temporary release of STR_PTR. */
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- zerolength = compile_ref_checks(common, ccbegin, NULL);
- /* Restore if not zero length. */
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- }
- else
- {
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
- }
-
- if (min > 1 || max > 1)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
-
- label = LABEL();
- compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
-
- if (min > 1 || max > 1)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
- if (min > 1)
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
- if (max > 1)
- {
- jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- JUMPHERE(jump);
- }
- }
-
- if (max == 0)
- {
- /* Includes min > 1 case as well. */
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- }
-
- JUMPHERE(zerolength);
- BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
-
- decrease_call_count(common);
- return cc;
- }
-
-allocate_stack(common, 2);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
-if (type != OP_CRMINSTAR)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
-
-if (min == 0)
- {
- zerolength = compile_ref_checks(common, ccbegin, NULL);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- jump = JUMP(SLJIT_JUMP);
- }
-else
- zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
-
-BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
-if (max > 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
-
-compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
-if (min > 1)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
- }
-else if (max > 0)
- OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
-
-if (jump != NULL)
- JUMPHERE(jump);
-JUMPHERE(zerolength);
-
-decrease_call_count(common);
-return cc;
-}
-
-static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-recurse_entry *entry = common->entries;
-recurse_entry *prev = NULL;
-int start = GET(cc, 1);
-
-PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
-while (entry != NULL)
- {
- if (entry->start == start)
- break;
- prev = entry;
- entry = entry->next;
- }
-
-if (entry == NULL)
- {
- entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- entry->next = NULL;
- entry->entry = NULL;
- entry->calls = NULL;
- entry->start = start;
-
- if (prev != NULL)
- prev->next = entry;
- else
- common->entries = entry;
- }
-
-if (common->has_set_som && common->mark_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- }
-else if (common->has_set_som || common->mark_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
-
-if (entry->entry == NULL)
- add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
-else
- JUMPTO(SLJIT_FAST_CALL, entry->entry);
-/* Leave if the match is failed. */
-add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
-return cc + 1 + LINK_SIZE;
-}
-
-static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
-{
-DEFINE_COMPILER;
-int framesize;
-int localptr;
-backtrack_common altbacktrack;
-pcre_uchar *ccbegin;
-pcre_uchar opcode;
-pcre_uchar bra = OP_BRA;
-jump_list *tmp = NULL;
-jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
-jump_list **found;
-/* Saving previous accept variables. */
-struct sljit_label *save_leavelabel = common->leavelabel;
-struct sljit_label *save_acceptlabel = common->acceptlabel;
-jump_list *save_leave = common->leave;
-jump_list *save_accept = common->accept;
-struct sljit_jump *jump;
-struct sljit_jump *brajump = NULL;
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- SLJIT_ASSERT(!conditional);
- bra = *cc;
- cc++;
- }
-localptr = PRIV_DATA(cc);
-SLJIT_ASSERT(localptr != 0);
-framesize = get_framesize(common, cc, FALSE);
-backtrack->framesize = framesize;
-backtrack->localptr = localptr;
-opcode = *cc;
-SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
-found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
-ccbegin = cc;
-cc += GET(cc, 1);
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a braminzero backtrack path. */
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
-
-if (framesize < 0)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
-else
- {
- allocate_stack(common, framesize + 2);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- init_frame(common, ccbegin, framesize + 1, 2, FALSE);
- }
-
-memset(&altbacktrack, 0, sizeof(backtrack_common));
-common->leavelabel = NULL;
-common->leave = NULL;
-while (1)
- {
- common->acceptlabel = NULL;
- common->accept = NULL;
- altbacktrack.top = NULL;
- altbacktrack.topbacktracks = NULL;
-
- if (*ccbegin == OP_ALT)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- altbacktrack.cc = ccbegin;
- compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->leavelabel = save_leavelabel;
- common->acceptlabel = save_acceptlabel;
- common->leave = save_leave;
- common->accept = save_accept;
- return NULL;
- }
- common->acceptlabel = LABEL();
- if (common->accept != NULL)
- set_jumps(common->accept, common->acceptlabel);
-
- /* Reset stack. */
- if (framesize < 0)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- else {
- if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
- {
- /* We don't need to keep the STR_PTR, only the previous localptr. */
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
- }
- else
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- }
- }
-
- if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
- {
- /* We know that STR_PTR was stored on the top of the stack. */
- if (conditional)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
- else if (bra == OP_BRAZERO)
- {
- if (framesize < 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
- }
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else if (framesize >= 0)
- {
- /* For OP_BRA and OP_BRAMINZERO. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
- }
- }
- add_jump(compiler, found, JUMP(SLJIT_JUMP));
-
- compile_backtrackpath(common, altbacktrack.top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->leavelabel = save_leavelabel;
- common->acceptlabel = save_acceptlabel;
- common->leave = save_leave;
- common->accept = save_accept;
- return NULL;
- }
- set_jumps(altbacktrack.topbacktracks, LABEL());
-
- if (*cc != OP_ALT)
- break;
-
- ccbegin = cc;
- cc += GET(cc, 1);
- }
-/* None of them matched. */
-if (common->leave != NULL)
- set_jumps(common->leave, LABEL());
-
-if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
- {
- /* Assert is failed. */
- if (conditional || bra == OP_BRAZERO)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- if (framesize < 0)
- {
- /* The topmost item should be 0. */
- if (bra == OP_BRAZERO)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- else
- free_stack(common, 1);
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* The topmost item should be 0. */
- if (bra == OP_BRAZERO)
- {
- free_stack(common, framesize + 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else
- free_stack(common, framesize + 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
- }
- jump = JUMP(SLJIT_JUMP);
- if (bra != OP_BRAZERO)
- add_jump(compiler, target, jump);
-
- /* Assert is successful. */
- set_jumps(tmp, LABEL());
- if (framesize < 0)
- {
- /* We know that STR_PTR was stored on the top of the stack. */
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
- /* Keep the STR_PTR on the top of the stack. */
- if (bra == OP_BRAZERO)
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- else if (bra == OP_BRAMINZERO)
- {
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- }
- else
- {
- if (bra == OP_BRA)
- {
- /* We don't need to keep the STR_PTR, only the previous localptr. */
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
- }
- else
- {
- /* We don't need to keep the STR_PTR, only the previous localptr. */
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
- }
- }
-
- if (bra == OP_BRAZERO)
- {
- backtrack->trypath = LABEL();
- sljit_set_label(jump, backtrack->trypath);
- }
- else if (bra == OP_BRAMINZERO)
- {
- JUMPTO(SLJIT_JUMP, backtrack->trypath);
- JUMPHERE(brajump);
- if (framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
- }
- set_jumps(backtrack->common.topbacktracks, LABEL());
- }
- }
-else
- {
- /* AssertNot is successful. */
- if (framesize < 0)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (bra != OP_BRA)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- else
- free_stack(common, 1);
- }
- else
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* The topmost item should be 0. */
- if (bra != OP_BRA)
- {
- free_stack(common, framesize + 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else
- free_stack(common, framesize + 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
- }
-
- if (bra == OP_BRAZERO)
- backtrack->trypath = LABEL();
- else if (bra == OP_BRAMINZERO)
- {
- JUMPTO(SLJIT_JUMP, backtrack->trypath);
- JUMPHERE(brajump);
- }
-
- if (bra != OP_BRA)
- {
- SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
- set_jumps(backtrack->common.topbacktracks, LABEL());
- backtrack->common.topbacktracks = NULL;
- }
- }
-
-common->leavelabel = save_leavelabel;
-common->acceptlabel = save_acceptlabel;
-common->leave = save_leave;
-common->accept = save_accept;
-return cc + 1 + LINK_SIZE;
-}
-
-static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
-{
-int condition = FALSE;
-pcre_uchar *slotA = name_table;
-pcre_uchar *slotB;
-sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
-sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
-sljit_w no_capture;
-int i;
-
-locals += refno & 0xff;
-refno >>= 8;
-no_capture = locals[1];
-
-for (i = 0; i < name_count; i++)
- {
- if (GET2(slotA, 0) == refno) break;
- slotA += name_entry_size;
- }
-
-if (i < name_count)
- {
- /* Found a name for the number - there can be only one; duplicate names
- for different numbers are allowed, but not vice versa. First scan down
- for duplicates. */
-
- slotB = slotA;
- while (slotB > name_table)
- {
- slotB -= name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = locals[GET2(slotB, 0) << 1] != no_capture;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < name_count; i++)
- {
- slotB += name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = locals[GET2(slotB, 0) << 1] != no_capture;
- if (condition) break;
- }
- else break;
- }
- }
- }
-return condition;
-}
-
-static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
-{
-int condition = FALSE;
-pcre_uchar *slotA = name_table;
-pcre_uchar *slotB;
-sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
-sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
-sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
-int i;
-
-for (i = 0; i < name_count; i++)
- {
- if (GET2(slotA, 0) == recno) break;
- slotA += name_entry_size;
- }
-
-if (i < name_count)
- {
- /* Found a name for the number - there can be only one; duplicate
- names for different numbers are allowed, but not vice versa. First
- scan down for duplicates. */
-
- slotB = slotA;
- while (slotB > name_table)
- {
- slotB -= name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == group_num;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < name_count; i++)
- {
- slotB += name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == group_num;
- if (condition) break;
- }
- else break;
- }
- }
- }
-return condition;
-}
-
-/*
- Handling bracketed expressions is probably the most complex part.
-
- Stack layout naming characters:
- S - Push the current STR_PTR
- 0 - Push a 0 (NULL)
- A - Push the current STR_PTR. Needed for restoring the STR_PTR
- before the next alternative. Not pushed if there are no alternatives.
- M - Any values pushed by the current alternative. Can be empty, or anything.
- C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
- L - Push the previous local (pointed by localptr) to the stack
- () - opional values stored on the stack
- ()* - optonal, can be stored multiple times
-
- The following list shows the regular expression templates, their PCRE byte codes
- and stack layout supported by pcre-sljit.
-
- (?:) OP_BRA | OP_KET A M
- () OP_CBRA | OP_KET C M
- (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
- OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
- (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
- OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
- ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
- OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
- ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
- OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
- (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
- (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
- ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
- ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
- (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
- OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
- (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
- OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
- ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
- OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
- ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
- OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
-
-
- Stack layout naming characters:
- A - Push the alternative index (starting from 0) on the stack.
- Not pushed if there is no alternatives.
- M - Any values pushed by the current alternative. Can be empty, or anything.
-
- The next list shows the possible content of a bracket:
- (|) OP_*BRA | OP_ALT ... M A
- (?()|) OP_*COND | OP_ALT M A
- (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
- (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
- Or nothing, if trace is unnecessary
-*/
-
-static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-pcre_uchar opcode;
-int localptr = 0;
-int offset = 0;
-int stacksize;
-pcre_uchar *ccbegin;
-pcre_uchar *trypath;
-pcre_uchar bra = OP_BRA;
-pcre_uchar ket;
-assert_backtrack *assert;
-BOOL has_alternatives;
-struct sljit_jump *jump;
-struct sljit_jump *skip;
-struct sljit_label *rmaxlabel = NULL;
-struct sljit_jump *braminzerojump = NULL;
-
-PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- bra = *cc;
- cc++;
- opcode = *cc;
- }
-
-opcode = *cc;
-ccbegin = cc;
-trypath = ccbegin + 1 + LINK_SIZE;
-
-if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
- {
- /* Drop this bracket_backtrack. */
- parent->top = backtrack->prev;
- return bracketend(cc);
- }
-
-ket = *(bracketend(cc) - 1 - LINK_SIZE);
-SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
-SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
-cc += GET(cc, 1);
-
-has_alternatives = *cc == OP_ALT;
-if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- {
- has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
- if (*trypath == OP_NRREF)
- {
- stacksize = GET2(trypath, 1);
- if (common->currententry == NULL || stacksize == RREF_ANY)
- has_alternatives = FALSE;
- else if (common->currententry->start == 0)
- has_alternatives = stacksize != 0;
- else
- has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
- }
- }
-
-if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
- opcode = OP_SCOND;
-if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
- opcode = OP_ONCE;
-
-if (opcode == OP_CBRA || opcode == OP_SCBRA)
- {
- /* Capturing brackets has a pre-allocated space. */
- offset = GET2(ccbegin, 1 + LINK_SIZE);
- localptr = OVECTOR_PRIV(offset);
- offset <<= 1;
- BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
- trypath += IMM2_SIZE;
- }
-else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
- {
- /* Other brackets simply allocate the next entry. */
- localptr = PRIV_DATA(ccbegin);
- SLJIT_ASSERT(localptr != 0);
- BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
- if (opcode == OP_ONCE)
- BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
- }
-
-/* Instructions before the first alternative. */
-stacksize = 0;
-if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
- stacksize++;
-if (bra == OP_BRAZERO)
- stacksize++;
-
-if (stacksize > 0)
- allocate_stack(common, stacksize);
-
-stacksize = 0;
-if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
-if (bra == OP_BRAZERO)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (ket != OP_KETRMIN)
- {
- free_stack(common, 1);
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
- else
- {
- if (opcode == OP_ONCE || opcode >= OP_SBRA)
- {
- jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* Nothing stored during the first run. */
- skip = JUMP(SLJIT_JUMP);
- JUMPHERE(jump);
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
- {
- /* When we come from outside, localptr contains the previous STR_PTR. */
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- }
- else
- {
- /* Except when the whole stack frame must be saved. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
- }
- JUMPHERE(skip);
- }
- else
- {
- jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- JUMPHERE(jump);
- }
- }
- }
-
-if (ket == OP_KETRMIN)
- BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
-
-if (ket == OP_KETRMAX)
- {
- rmaxlabel = LABEL();
- if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
- BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
- }
-
-/* Handling capturing brackets and alternatives. */
-if (opcode == OP_ONCE)
- {
- if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
- {
- /* Neither capturing brackets nor recursions are not found in the block. */
- if (ket == OP_KETRMIN)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- }
- else if (ket == OP_KETRMAX || has_alternatives)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
- }
- else
- {
- if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
- {
- allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
- }
- else
- {
- allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
- }
- }
- }
-else if (opcode == OP_CBRA || opcode == OP_SCBRA)
- {
- /* Saving the previous values. */
- allocate_stack(common, 3);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
- }
-else if (opcode == OP_SBRA || opcode == OP_SCOND)
- {
- /* Saving the previous value. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
-else if (has_alternatives)
- {
- /* Pushing the starting string pointer. */
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
-
-/* Generating code for the first alternative. */
-if (opcode == OP_COND || opcode == OP_SCOND)
- {
- if (*trypath == OP_CREF)
- {
- SLJIT_ASSERT(has_alternatives);
- add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
- CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
- trypath += 1 + IMM2_SIZE;
- }
- else if (*trypath == OP_NCREF)
- {
- SLJIT_ASSERT(has_alternatives);
- stacksize = GET2(trypath, 1);
- jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
-
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
- GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
- sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
- add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
-
- JUMPHERE(jump);
- trypath += 1 + IMM2_SIZE;
- }
- else if (*trypath == OP_RREF || *trypath == OP_NRREF)
- {
- /* Never has other case. */
- BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
-
- stacksize = GET2(trypath, 1);
- if (common->currententry == NULL)
- stacksize = 0;
- else if (stacksize == RREF_ANY)
- stacksize = 1;
- else if (common->currententry->start == 0)
- stacksize = stacksize == 0;
- else
- stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
-
- if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
- {
- SLJIT_ASSERT(!has_alternatives);
- if (stacksize != 0)
- trypath += 1 + IMM2_SIZE;
- else
- {
- if (*cc == OP_ALT)
- {
- trypath = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- }
- else
- trypath = cc;
- }
- }
- else
- {
- SLJIT_ASSERT(has_alternatives);
-
- stacksize = GET2(trypath, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
- GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
- OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
- sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
- add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
- trypath += 1 + IMM2_SIZE;
- }
- }
- else
- {
- SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
- /* Similar code as PUSH_BACKTRACK macro. */
- assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- memset(assert, 0, sizeof(assert_backtrack));
- assert->common.cc = trypath;
- BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
- trypath = compile_assert_trypath(common, trypath, assert, TRUE);
- }
- }
-
-compile_trypath(common, trypath, cc, backtrack);
-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), localptr);
- /* TMP2 which is set here used by OP_KETRMAX below. */
- if (ket == OP_KETRMAX)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
- else if (ket == OP_KETRMIN)
- {
- /* Move the STR_PTR to the localptr. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
- }
- }
- else
- {
- stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
- if (ket == OP_KETRMAX)
- {
- /* TMP2 which is set here used by OP_KETRMAX below. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- }
- }
-
-stacksize = 0;
-if (ket != OP_KET || bra != OP_BRA)
- stacksize++;
-if (has_alternatives && opcode != OP_ONCE)
- stacksize++;
-
-if (stacksize > 0)
- allocate_stack(common, stacksize);
-
-stacksize = 0;
-if (ket != OP_KET)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- stacksize++;
- }
-else if (bra != OP_BRA)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
-if (has_alternatives)
- {
- if (opcode != OP_ONCE)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- if (ket != OP_KETRMAX)
- BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
- }
-
-/* Must be after the trypath label. */
-if (offset != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
- }
-
-if (ket == OP_KETRMAX)
- {
- if (opcode == OP_ONCE || opcode >= OP_SBRA)
- {
- if (has_alternatives)
- BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE)
- {
- CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
- /* 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);
- }
- else
- JUMPTO(SLJIT_JUMP, rmaxlabel);
- BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
- }
-
-if (bra == OP_BRAZERO)
- BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
- JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
- if (braminzerojump != NULL)
- {
- JUMPHERE(braminzerojump);
- /* 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. */
- if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- }
- else if (ket == OP_KETRMIN && opcode != OP_ONCE)
- free_stack(common, 1);
- }
- /* Continue to the normal backtrack. */
- }
-
-if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
- decrease_call_count(common);
-
-/* Skip the other alternatives. */
-while (*cc == OP_ALT)
- cc += GET(cc, 1);
-cc += 1 + LINK_SIZE;
-return cc;
-}
-
-static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-pcre_uchar opcode;
-int localptr;
-int cbraprivptr = 0;
-int framesize;
-int stacksize;
-int offset = 0;
-BOOL zero = FALSE;
-pcre_uchar *ccbegin = NULL;
-int stack;
-struct sljit_label *loop = NULL;
-struct jump_list *emptymatch = NULL;
-
-PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
-if (*cc == OP_BRAPOSZERO)
- {
- zero = TRUE;
- cc++;
- }
-
-opcode = *cc;
-localptr = PRIV_DATA(cc);
-SLJIT_ASSERT(localptr != 0);
-BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
-switch(opcode)
- {
- case OP_BRAPOS:
- case OP_SBRAPOS:
- ccbegin = cc + 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- offset = GET2(cc, 1 + LINK_SIZE);
- cbraprivptr = OVECTOR_PRIV(offset);
- offset <<= 1;
- ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
-
-framesize = get_framesize(common, cc, FALSE);
-BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
-if (framesize < 0)
- {
- stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
- if (!zero)
- stacksize++;
- BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
- allocate_stack(common, stacksize);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
-
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- }
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
- if (!zero)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
- }
-else
- {
- stacksize = framesize + 1;
- if (!zero)
- stacksize++;
- if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
- stacksize++;
- BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
- allocate_stack(common, stacksize);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
- stack = 0;
- if (!zero)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
- stack++;
- }
- if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
- stack++;
- }
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
- init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
- }
-
-if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
-
-loop = LABEL();
-while (*cc != OP_KETRPOS)
- {
- backtrack->top = NULL;
- backtrack->topbacktracks = NULL;
- cc += GET(cc, 1);
-
- compile_trypath(common, ccbegin, cc, backtrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
-
- if (framesize < 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
-
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
- }
- else
- {
- if (opcode == OP_SBRAPOS)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
-
- if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
- add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
-
- if (!zero)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
- }
- else
- {
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- {
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
- if (opcode == OP_SBRAPOS)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
- }
-
- if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
- add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
-
- if (!zero)
- {
- if (framesize < 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- }
- JUMPTO(SLJIT_JUMP, loop);
- flush_stubs(common);
-
- compile_backtrackpath(common, backtrack->top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- set_jumps(backtrack->topbacktracks, LABEL());
-
- if (framesize < 0)
- {
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
- else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- else
- {
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
- {
- /* Last alternative. */
- if (*cc == OP_KETRPOS)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
- }
- }
-
- if (*cc == OP_KETRPOS)
- break;
- ccbegin = cc + 1 + LINK_SIZE;
- }
-
-backtrack->topbacktracks = NULL;
-if (!zero)
- {
- if (framesize < 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
- else /* TMP2 is set to [localptr] above. */
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
- }
-
-/* None of them matched. */
-set_jumps(emptymatch, LABEL());
-decrease_call_count(common);
-return cc + 1 + LINK_SIZE;
-}
-
-static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
-{
-int class_len;
-
-*opcode = *cc;
-if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
- {
- cc++;
- *type = OP_CHAR;
- }
-else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
- {
- cc++;
- *type = OP_CHARI;
- *opcode -= OP_STARI - OP_STAR;
- }
-else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
- {
- cc++;
- *type = OP_NOT;
- *opcode -= OP_NOTSTAR - OP_STAR;
- }
-else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
- {
- cc++;
- *type = OP_NOTI;
- *opcode -= OP_NOTSTARI - OP_STAR;
- }
-else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
- {
- cc++;
- *opcode -= OP_TYPESTAR - OP_STAR;
- *type = 0;
- }
-else
- {
- SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
- *type = *opcode;
- cc++;
- class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
- *opcode = cc[class_len - 1];
- if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
- {
- *opcode -= OP_CRSTAR - OP_STAR;
- if (end != NULL)
- *end = cc + class_len;
- }
- else
- {
- SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
- *arg1 = GET2(cc, (class_len + IMM2_SIZE));
- *arg2 = GET2(cc, class_len);
-
- if (*arg2 == 0)
- {
- SLJIT_ASSERT(*arg1 != 0);
- *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
- }
- if (*arg1 == *arg2)
- *opcode = OP_EXACT;
-
- if (end != NULL)
- *end = cc + class_len + 2 * IMM2_SIZE;
- }
- return cc;
- }
-
-if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
- {
- *arg1 = GET2(cc, 0);
- cc += IMM2_SIZE;
- }
-
-if (*type == 0)
- {
- *type = *cc;
- if (end != NULL)
- *end = next_opcode(common, cc);
- cc++;
- return cc;
- }
-
-if (end != NULL)
- {
- *end = cc + 1;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
-#endif
- }
-return cc;
-}
-
-static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-pcre_uchar opcode;
-pcre_uchar type;
-int arg1 = -1, arg2 = -1;
-pcre_uchar* end;
-jump_list *nomatch = NULL;
-struct sljit_jump *jump = NULL;
-struct sljit_label *label;
-
-PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
-
-cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
-
-switch(opcode)
- {
- case OP_STAR:
- case OP_PLUS:
- case OP_UPTO:
- case OP_CRRANGE:
- if (type == OP_ANYNL || type == OP_EXTUNI)
- {
- if (opcode == OP_STAR || opcode == OP_UPTO)
- {
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
- }
- else
- {
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- if (opcode == OP_UPTO || opcode == OP_CRRANGE)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
-
- label = LABEL();
- compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
- if (opcode == OP_UPTO || opcode == OP_CRRANGE)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- if (opcode == OP_CRRANGE && arg2 > 0)
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
- if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
- jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
- }
-
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- if (jump != NULL)
- JUMPHERE(jump);
- }
- else
- {
- if (opcode == OP_PLUS)
- compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
- label = LABEL();
- compile_char1_trypath(common, type, cc, &nomatch);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
- {
- OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
- JUMPTO(SLJIT_JUMP, label);
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
- }
- set_jumps(nomatch, LABEL());
- if (opcode == OP_CRRANGE)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
- break;
-
- case OP_MINSTAR:
- case OP_MINPLUS:
- if (opcode == OP_MINPLUS)
- compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
- break;
-
- case OP_MINUPTO:
- case OP_CRMINRANGE:
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
- if (opcode == OP_CRMINRANGE)
- add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
- BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
- break;
-
- case OP_QUERY:
- case OP_MINQUERY:
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- if (opcode == OP_QUERY)
- compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
- BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
- break;
-
- case OP_EXACT:
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
- label = LABEL();
- compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
- break;
-
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSUPTO:
- if (opcode != OP_POSSTAR)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
- label = LABEL();
- compile_char1_trypath(common, type, cc, &nomatch);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
- if (opcode != OP_POSUPTO)
- {
- if (opcode == OP_POSPLUS)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
- JUMPTO(SLJIT_JUMP, label);
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
- }
- set_jumps(nomatch, LABEL());
- if (opcode == OP_POSPLUS)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
- break;
-
- case OP_POSQUERY:
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
- compile_char1_trypath(common, type, cc, &nomatch);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
- set_jumps(nomatch, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
-
-decrease_call_count(common);
-return end;
-}
-
-static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-
-PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
-
-if (*cc == OP_FAIL)
- {
- add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
- return cc + 1;
- }
-
-if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
- {
- /* No need to check notempty conditions. */
- if (common->acceptlabel == NULL)
- add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
- else
- JUMPTO(SLJIT_JUMP, common->acceptlabel);
- return cc + 1;
- }
-
-if (common->acceptlabel == NULL)
- add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
-else
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
-add_jump(compiler, &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)
- add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
-else
- CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-if (common->acceptlabel == NULL)
- add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
-else
- CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
-return cc + 1;
-}
-
-static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)
-{
-DEFINE_COMPILER;
-int offset = GET2(cc, 1);
-
-/* Data will be discarded anyway... */
-if (common->currententry != NULL)
- return cc + 1 + IMM2_SIZE;
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
-offset <<= 1;
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
-return cc + 1 + IMM2_SIZE;
-}
-
-static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_NOTPROP:
- case OP_PROP:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_NOT:
- case OP_NOTI:
- case OP_REVERSE:
- cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- break;
-
- case OP_SET_SOM:
- PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- cc++;
- break;
-
- case OP_CHAR:
- case OP_CHARI:
- if (common->mode == JIT_COMPILE)
- cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- else
- cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- cc = compile_iterator_trypath(common, cc, parent);
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
- if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
- cc = compile_iterator_trypath(common, cc, parent);
- else
- cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- break;
-
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16
- case OP_XCLASS:
- if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
- cc = compile_iterator_trypath(common, cc, parent);
- else
- cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- break;
-#endif
-
- case OP_REF:
- case OP_REFI:
- if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
- cc = compile_ref_iterator_trypath(common, cc, parent);
- else
- cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
- break;
-
- case OP_RECURSE:
- cc = compile_recurse_trypath(common, cc, parent);
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
- cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
- break;
-
- case OP_BRAMINZERO:
- PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
- cc = bracketend(cc + 1);
- if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
- {
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
- else
- {
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
- }
- BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
- if (cc[1] > OP_ASSERTBACK_NOT)
- decrease_call_count(common);
- break;
-
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRA:
- case OP_CBRA:
- case OP_COND:
- case OP_SBRA:
- case OP_SCBRA:
- case OP_SCOND:
- cc = compile_bracket_trypath(common, cc, parent);
- break;
-
- case OP_BRAZERO:
- if (cc[1] > OP_ASSERTBACK_NOT)
- cc = compile_bracket_trypath(common, cc, parent);
- else
- {
- PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
- cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
- }
- break;
-
- case OP_BRAPOS:
- case OP_CBRAPOS:
- case OP_SBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- cc = compile_bracketpos_trypath(common, cc, parent);
- break;
-
- case OP_MARK:
- 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);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(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);
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_COMMIT:
- PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
- cc += 1;
- break;
-
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- cc = compile_fail_accept_trypath(common, cc, parent);
- break;
-
- case OP_CLOSE:
- cc = compile_close_trypath(common, cc);
- break;
-
- case OP_SKIPZERO:
- cc = bracketend(cc + 1);
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- return;
- }
- if (cc == NULL)
- return;
- }
-SLJIT_ASSERT(cc == ccend);
-}
-
-#undef PUSH_BACKTRACK
-#undef PUSH_BACKTRACK_NOVALUE
-#undef BACKTRACK_AS
-
-#define COMPILE_BACKTRACKPATH(current) \
- do \
- { \
- compile_backtrackpath(common, (current)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return; \
- } \
- while (0)
-
-#define CURRENT_AS(type) ((type *)current)
-
-static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-pcre_uchar *cc = current->cc;
-pcre_uchar opcode;
-pcre_uchar type;
-int arg1 = -1, arg2 = -1;
-struct sljit_label *label = NULL;
-struct sljit_jump *jump = NULL;
-jump_list *jumplist = NULL;
-
-cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
-
-switch(opcode)
- {
- case OP_STAR:
- case OP_PLUS:
- case OP_UPTO:
- case OP_CRRANGE:
- if (type == OP_ANYNL || type == OP_EXTUNI)
- {
- set_jumps(current->topbacktracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
- }
- else
- {
- if (opcode <= OP_PLUS || opcode == OP_UPTO)
- arg2 = 0;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
- OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- skip_char_back(common);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
- if (opcode == OP_CRRANGE)
- set_jumps(current->topbacktracks, LABEL());
- JUMPHERE(jump);
- free_stack(common, 2);
- if (opcode == OP_PLUS)
- set_jumps(current->topbacktracks, LABEL());
- }
- break;
-
- case OP_MINSTAR:
- case OP_MINPLUS:
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- compile_char1_trypath(common, type, cc, &jumplist);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
- set_jumps(jumplist, LABEL());
- free_stack(common, 1);
- if (opcode == OP_MINPLUS)
- set_jumps(current->topbacktracks, LABEL());
- break;
-
- case OP_MINUPTO:
- case OP_CRMINRANGE:
- if (opcode == OP_CRMINRANGE)
- {
- label = LABEL();
- set_jumps(current->topbacktracks, label);
- }
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- compile_char1_trypath(common, type, cc, &jumplist);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
-
- if (opcode == OP_CRMINRANGE)
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
-
- if (opcode == OP_CRMINRANGE && arg1 == 0)
- JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
- else
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);
-
- set_jumps(jumplist, LABEL());
- free_stack(common, 2);
- break;
-
- case OP_QUERY:
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
- jump = JUMP(SLJIT_JUMP);
- set_jumps(current->topbacktracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
- JUMPHERE(jump);
- free_stack(common, 1);
- break;
-
- case OP_MINQUERY:
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- compile_char1_trypath(common, type, cc, &jumplist);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
- set_jumps(jumplist, LABEL());
- JUMPHERE(jump);
- free_stack(common, 1);
- break;
-
- case OP_EXACT:
- case OP_POSPLUS:
- set_jumps(current->topbacktracks, LABEL());
- break;
-
- case OP_POSSTAR:
- case OP_POSQUERY:
- case OP_POSUPTO:
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
-}
-
-static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-pcre_uchar *cc = current->cc;
-pcre_uchar type;
-
-type = cc[1 + IMM2_SIZE];
-if ((type & 0x1) == 0)
- {
- set_jumps(current->topbacktracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
- return;
- }
-
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
-set_jumps(current->topbacktracks, LABEL());
-free_stack(common, 2);
-}
-
-static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-
-set_jumps(current->topbacktracks, LABEL());
-
-if (common->has_set_som && common->mark_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- free_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
- }
-else if (common->has_set_som || common->mark_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
- }
-}
-
-static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-pcre_uchar *cc = current->cc;
-pcre_uchar bra = OP_BRA;
-struct sljit_jump *brajump = NULL;
-
-SLJIT_ASSERT(*cc != OP_BRAMINZERO);
-if (*cc == OP_BRAZERO)
- {
- bra = *cc;
- cc++;
- }
-
-if (bra == OP_BRAZERO)
- {
- SLJIT_ASSERT(current->topbacktracks == NULL);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
-
-if (CURRENT_AS(assert_backtrack)->framesize < 0)
- {
- set_jumps(current->topbacktracks, LABEL());
-
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
- free_stack(common, 1);
- }
- return;
- }
-
-if (bra == OP_BRAZERO)
- {
- if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
- free_stack(common, 1);
- return;
- }
- free_stack(common, 1);
- brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
-
-if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
-
- set_jumps(current->topbacktracks, LABEL());
- }
-else
- set_jumps(current->topbacktracks, LABEL());
-
-if (bra == OP_BRAZERO)
- {
- /* We know there is enough place on the stack. */
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);
- JUMPHERE(brajump);
- }
-}
-
-static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-int opcode;
-int offset = 0;
-int localptr = CURRENT_AS(bracket_backtrack)->localptr;
-int stacksize;
-int count;
-pcre_uchar *cc = current->cc;
-pcre_uchar *ccbegin;
-pcre_uchar *ccprev;
-jump_list *jumplist = NULL;
-jump_list *jumplistitem = NULL;
-pcre_uchar bra = OP_BRA;
-pcre_uchar ket;
-assert_backtrack *assert;
-BOOL has_alternatives;
-struct sljit_jump *brazero = NULL;
-struct sljit_jump *once = NULL;
-struct sljit_jump *cond = NULL;
-struct sljit_label *rminlabel = NULL;
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- bra = *cc;
- cc++;
- }
-
-opcode = *cc;
-ccbegin = cc;
-ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
-cc += GET(cc, 1);
-has_alternatives = *cc == OP_ALT;
-if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
-if (opcode == OP_CBRA || opcode == OP_SCBRA)
- offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
-if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
- opcode = OP_SCOND;
-if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
- opcode = OP_ONCE;
-
-if (ket == OP_KETRMAX)
- {
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
- }
-else if (ket == OP_KETRMIN)
- {
- if (bra != OP_BRAMINZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (opcode >= OP_SBRA || opcode == OP_ONCE)
- {
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);
- }
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- }
- else
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);
- }
- rminlabel = LABEL();
- }
-else if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
-
-if (SLJIT_UNLIKELY(opcode == OP_ONCE))
- {
- if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- }
- once = JUMP(SLJIT_JUMP);
- }
-else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- {
- if (has_alternatives)
- {
- /* Always exactly one alternative. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
-
- jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
- if (SLJIT_UNLIKELY(!jumplistitem))
- return;
- jumplist = jumplistitem;
- jumplistitem->next = NULL;
- jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
- }
- }
-else if (*cc == OP_ALT)
- {
- /* Build a jump list. Get the last successfully matched branch index. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- count = 1;
- do
- {
- /* Append as the last item. */
- if (jumplist != NULL)
- {
- jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
- jumplistitem = jumplistitem->next;
- }
- else
- {
- jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
- jumplist = jumplistitem;
- }
-
- if (SLJIT_UNLIKELY(!jumplistitem))
- return;
-
- jumplistitem->next = NULL;
- jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
- cc += GET(cc, 1);
- }
- while (*cc == OP_ALT);
-
- cc = ccbegin + GET(ccbegin, 1);
- }
-
-COMPILE_BACKTRACKPATH(current->top);
-if (current->topbacktracks)
- set_jumps(current->topbacktracks, LABEL());
-
-if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- {
- /* Conditional block always has at most one alternative. */
- if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
- {
- SLJIT_ASSERT(has_alternatives);
- assert = CURRENT_AS(bracket_backtrack)->u.assert;
- if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
- }
- cond = JUMP(SLJIT_JUMP);
- set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
- }
- else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
- {
- SLJIT_ASSERT(has_alternatives);
- cond = JUMP(SLJIT_JUMP);
- set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
- }
- else
- SLJIT_ASSERT(!has_alternatives);
- }
-
-if (has_alternatives)
- {
- count = 1;
- do
- {
- current->top = NULL;
- current->topbacktracks = NULL;
- current->nextbacktracks = NULL;
- if (*cc == OP_ALT)
- {
- ccprev = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- if (opcode != OP_COND && opcode != OP_SCOND)
- {
- if (localptr != 0 && opcode != OP_ONCE)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- compile_trypath(common, ccprev, cc, current);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return;
- }
-
- /* Instructions after the current alternative is succesfully matched. */
- /* There is a similar code in compile_bracket_trypath. */
- if (opcode == OP_ONCE)
- {
- if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- /* TMP2 which is set here used by OP_KETRMAX below. */
- if (ket == OP_KETRMAX)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
- else if (ket == OP_KETRMIN)
- {
- /* Move the STR_PTR to the localptr. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
- }
- }
- else
- {
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
- if (ket == OP_KETRMAX)
- {
- /* TMP2 which is set here used by OP_KETRMAX below. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- }
- }
-
- stacksize = 0;
- if (opcode != OP_ONCE)
- stacksize++;
- if (ket != OP_KET || bra != OP_BRA)
- stacksize++;
-
- if (stacksize > 0) {
- if (opcode != OP_ONCE || CURRENT_AS(bracket_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_w));
- }
- }
-
- stacksize = 0;
- if (ket != OP_KET || bra != OP_BRA)
- {
- if (ket != OP_KET)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
- if (opcode != OP_ONCE)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
-
- if (offset != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
- }
-
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);
-
- if (opcode != OP_ONCE)
- {
- SLJIT_ASSERT(jumplist);
- JUMPHERE(jumplist->jump);
- jumplist = jumplist->next;
- }
-
- COMPILE_BACKTRACKPATH(current->top);
- if (current->topbacktracks)
- set_jumps(current->topbacktracks, LABEL());
- SLJIT_ASSERT(!current->nextbacktracks);
- }
- while (*cc == OP_ALT);
- SLJIT_ASSERT(!jumplist);
-
- if (cond != NULL)
- {
- 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->localptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
- }
- JUMPHERE(cond);
- }
-
- /* Free the STR_PTR. */
- if (localptr == 0)
- free_stack(common, 1);
- }
-
-if (offset != 0)
- {
- /* Using both tmp register is better for instruction scheduling. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
- free_stack(common, 3);
- }
-else if (opcode == OP_SBRA || opcode == OP_SCOND)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- }
-else if (opcode == OP_ONCE)
- {
- cc = ccbegin + GET(ccbegin, 1);
- if (CURRENT_AS(bracket_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);
- }
- else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
- {
- /* The STR_PTR must be released. */
- free_stack(common, 1);
- }
-
- JUMPHERE(once);
- /* Restore previous localptr */
- if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
- else if (ket == OP_KETRMIN)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* See the comment below. */
- free_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
- }
- }
-
-if (ket == OP_KETRMAX)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (bra != OP_BRAZERO)
- free_stack(common, 1);
- CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
- JUMPHERE(brazero);
- free_stack(common, 1);
- }
- }
-else if (ket == OP_KETRMIN)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- /* OP_ONCE removes everything in case of a backtrack, so we don't
- need to explicitly release the STR_PTR. The extra release would
- affect badly the free_stack(2) above. */
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
- if (opcode == OP_ONCE)
- free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
- else if (bra == OP_BRAMINZERO)
- free_stack(common, 1);
- }
-else if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
- JUMPHERE(brazero);
- }
-}
-
-static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-int offset;
-struct sljit_jump *jump;
-
-if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
- {
- if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
- {
- offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
- }
- set_jumps(current->topbacktracks, LABEL());
- free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
- return;
- }
-
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);
-add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-
-if (current->topbacktracks)
- {
- jump = JUMP(SLJIT_JUMP);
- set_jumps(current->topbacktracks, LABEL());
- /* Drop the stack frame. */
- free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
- JUMPHERE(jump);
- }
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
-}
-
-static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-assert_backtrack backtrack;
-
-current->top = NULL;
-current->topbacktracks = NULL;
-current->nextbacktracks = NULL;
-if (current->cc[1] > OP_ASSERTBACK_NOT)
- {
- /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */
- compile_bracket_trypath(common, current->cc, current);
- compile_bracket_backtrackpath(common, current->top);
- }
-else
- {
- memset(&backtrack, 0, sizeof(backtrack));
- backtrack.common.cc = current->cc;
- backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;
- /* Manual call of compile_assert_trypath. */
- compile_assert_trypath(common, current->cc, &backtrack, FALSE);
- }
-SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
-}
-
-static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-
-while (current)
- {
- if (current->nextbacktracks != NULL)
- set_jumps(current->nextbacktracks, LABEL());
- switch(*current->cc)
- {
- case OP_SET_SOM:
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
-#endif
- compile_iterator_backtrackpath(common, current);
- break;
-
- case OP_REF:
- case OP_REFI:
- compile_ref_iterator_backtrackpath(common, current);
- break;
-
- case OP_RECURSE:
- compile_recurse_backtrackpath(common, current);
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- compile_assert_backtrackpath(common, current);
- break;
-
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_BRA:
- case OP_CBRA:
- case OP_COND:
- case OP_SBRA:
- case OP_SCBRA:
- case OP_SCOND:
- compile_bracket_backtrackpath(common, current);
- break;
-
- case OP_BRAZERO:
- if (current->cc[1] > OP_ASSERTBACK_NOT)
- compile_bracket_backtrackpath(common, current);
- else
- compile_assert_backtrackpath(common, current);
- break;
-
- case OP_BRAPOS:
- case OP_CBRAPOS:
- case OP_SBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- compile_bracketpos_backtrackpath(common, current);
- break;
-
- case OP_BRAMINZERO:
- compile_braminzero_backtrackpath(common, current);
- break;
-
- case OP_MARK:
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
- break;
-
- case OP_COMMIT:
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
- if (common->leavelabel == NULL)
- add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
- else
- JUMPTO(SLJIT_JUMP, common->leavelabel);
- break;
-
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- set_jumps(current->topbacktracks, LABEL());
- break;
-
- default:
- SLJIT_ASSERT_STOP();
- break;
- }
- current = current->prev;
- }
-}
-
-static SLJIT_INLINE void compile_recurse(compiler_common *common)
-{
-DEFINE_COMPILER;
-pcre_uchar *cc = common->start + common->currententry->start;
-pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
-pcre_uchar *ccend = bracketend(cc);
-int localsize = get_localsize(common, ccbegin, ccend);
-int framesize = get_framesize(common, cc, TRUE);
-int alternativesize;
-BOOL needsframe;
-backtrack_common altbacktrack;
-struct sljit_label *save_leavelabel = common->leavelabel;
-jump_list *save_leave = common->leave;
-struct sljit_jump *jump;
-
-SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
-needsframe = framesize >= 0;
-if (!needsframe)
- framesize = 0;
-alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
-
-SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
-common->currententry->entry = LABEL();
-set_jumps(common->currententry->calls, common->currententry->entry);
-
-sljit_emit_fast_enter(compiler, TMP2, 0);
-allocate_stack(common, localsize + framesize + alternativesize);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
-copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
-if (needsframe)
- init_frame(common, cc, 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->leavelabel = NULL;
-common->acceptlabel = NULL;
-common->leave = NULL;
-common->accept = NULL;
-altbacktrack.cc = ccbegin;
-cc += GET(cc, 1);
-while (1)
- {
- altbacktrack.top = NULL;
- altbacktrack.topbacktracks = NULL;
-
- if (altbacktrack.cc != ccbegin)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->leavelabel = save_leavelabel;
- common->leave = save_leave;
- return;
- }
-
- add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
-
- compile_backtrackpath(common, altbacktrack.top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->leavelabel = save_leavelabel;
- common->leave = save_leave;
- return;
- }
- set_jumps(altbacktrack.topbacktracks, LABEL());
-
- if (*cc != OP_ALT)
- break;
-
- altbacktrack.cc = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- }
-/* None of them matched. */
-if (common->leave != NULL)
- set_jumps(common->leave, LABEL());
-
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
-jump = JUMP(SLJIT_JUMP);
-
-set_jumps(common->accept, LABEL());
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
-if (needsframe)
- {
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
- }
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
-
-JUMPHERE(jump);
-copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
-free_stack(common, localsize + framesize + alternativesize);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
-OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
-sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
-
-common->leavelabel = save_leavelabel;
-common->leave = save_leave;
-}
-
-#undef COMPILE_BACKTRACKPATH
-#undef CURRENT_AS
-
-void
-PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
-{
-struct sljit_compiler *compiler;
-backtrack_common rootbacktrack;
-compiler_common common_data;
-compiler_common *common = &common_data;
-const pcre_uint8 *tables = re->tables;
-pcre_study_data *study;
-int localsize;
-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_jump *jump;
-struct sljit_jump *reqbyte_notfound = NULL;
-struct sljit_jump *empty_match;
-
-SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
-study = extra->study_data;
-
-if (!tables)
- tables = PRIV(default_tables);
-
-memset(&rootbacktrack, 0, sizeof(backtrack_common));
-memset(common, 0, sizeof(compiler_common));
-rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
-
-common->start = rootbacktrack.cc;
-common->fcc = tables + fcc_offset;
-common->lcc = (sljit_w)(tables + lcc_offset);
-common->mode = mode;
-common->nltype = NLTYPE_FIXED;
-switch(re->options & PCRE_NEWLINE_BITS)
- {
- case 0:
- /* Compile-time default */
- switch (NEWLINE)
- {
- case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
- case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
- default: common->newline = NEWLINE; break;
- }
- break;
- case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
- case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
- default: return;
- }
-if ((re->options & PCRE_BSR_ANYCRLF) != 0)
- common->bsr_nltype = NLTYPE_ANYCRLF;
-else if ((re->options & PCRE_BSR_UNICODE) != 0)
- common->bsr_nltype = NLTYPE_ANY;
-else
- {
-#ifdef BSR_ANYCRLF
- common->bsr_nltype = NLTYPE_ANYCRLF;
-#else
- common->bsr_nltype = NLTYPE_ANY;
-#endif
- }
-common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-common->ctypes = (sljit_w)(tables + ctypes_offset);
-common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
-common->name_count = re->name_count;
-common->name_entry_size = re->name_entry_size;
-common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
-#ifdef SUPPORT_UTF
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-common->utf = (re->options & PCRE_UTF8) != 0;
-#ifdef SUPPORT_UCP
-common->use_ucp = (re->options & PCRE_UCP) != 0;
-#endif
-#endif /* SUPPORT_UTF */
-ccend = bracketend(rootbacktrack.cc);
-
-/* Calculate the local space size on the stack. */
-common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
-
-SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
-localsize = get_localspace(common, rootbacktrack.cc, ccend);
-if (localsize < 0)
- return;
-
-/* Checking flags and updating ovector_start. */
-if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
- {
- common->req_char_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- }
-if (mode != JIT_COMPILE)
- {
- common->start_used_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- if (mode == JIT_PARTIAL_SOFT_COMPILE)
- {
- common->hit_start = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- }
- }
-if ((re->options & PCRE_FIRSTLINE) != 0)
- {
- common->first_line_end = common->ovector_start;
- common->ovector_start += sizeof(sljit_w);
- }
-
-/* Aligning ovector to even number of sljit words. */
-if ((common->ovector_start & sizeof(sljit_w)) != 0)
- common->ovector_start += sizeof(sljit_w);
-
-SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
-common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
-localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
-if (localsize > SLJIT_MAX_LOCAL_SIZE)
- return;
-common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
-if (!common->localptrs)
- return;
-memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
-set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
-
-compiler = sljit_create_compiler();
-if (!compiler)
- {
- SLJIT_FREE(common->localptrs);
- return;
- }
-common->compiler = compiler;
-
-/* Main pcre_jit_exec entry. */
-sljit_emit_enter(compiler, 1, 5, 5, localsize);
-
-/* Register init. */
-reset_ovector(common, (re->top_bracket + 1) * 2);
-if (common->req_char_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
-
-OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
-
-if (mode == JIT_PARTIAL_SOFT_COMPILE)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, 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);
- /* Forward search if possible. */
- if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
- else if ((re->flags & PCRE_STARTLINE) != 0)
- fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
- else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
- fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
- }
- }
-if (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);
-/* 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);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-else if (mode == JIT_PARTIAL_HARD_COMPILE)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
-
-compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->localptrs);
- return;
- }
-
-empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
-empty_match_found = LABEL();
-
-common->acceptlabel = LABEL();
-if (common->accept != NULL)
- set_jumps(common->accept, common->acceptlabel);
-
-/* This means we have a match. Update the ovector. */
-copy_ovector(common, re->top_bracket + 1);
-common->leavelabel = LABEL();
-if (common->leave != NULL)
- set_jumps(common->leave, common->leavelabel);
-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->leavelabel);
- }
-
-empty_match_backtrack = LABEL();
-compile_backtrackpath(common, rootbacktrack.top);
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->localptrs);
- return;
- }
-
-SLJIT_ASSERT(rootbacktrack.prev == NULL);
-
-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);
- 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);
- JUMPHERE(jump);
- }
-
-/* Check we have remaining characters. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
-
-if ((re->options & PCRE_ANCHORED) == 0)
- {
- if ((re->options & PCRE_FIRSTLINE) == 0)
- {
- if (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);
- }
- 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);
- COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
- COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
- JUMPTO(SLJIT_C_ZERO, mainloop);
- }
- else
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
- }
- }
-
-/* No more remaining characters. */
-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);
-
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
-JUMPTO(SLJIT_JUMP, common->leavelabel);
-
-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);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
-CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
-JUMPTO(SLJIT_JUMP, empty_match_backtrack);
-
-common->currententry = common->entries;
-while (common->currententry != NULL)
- {
- /* Might add new entries. */
- compile_recurse(common);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->localptrs);
- return;
- }
- flush_stubs(common);
- common->currententry = common->currententry->next;
- }
-
-/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
-/* This is a (really) rare case. */
-set_jumps(common->stackalloc, LABEL());
-/* RETURN_ADDR is not a saved register. */
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
-OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
-
-sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
-jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
-sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
-
-/* Allocation failed. */
-JUMPHERE(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->leavelabel);
-
-/* Call limit reached. */
-set_jumps(common->calllimit, LABEL());
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
-JUMPTO(SLJIT_JUMP, common->leavelabel);
-
-if (common->revertframes != NULL)
- {
- set_jumps(common->revertframes, LABEL());
- do_revertframes(common);
- }
-if (common->wordboundary != NULL)
- {
- set_jumps(common->wordboundary, LABEL());
- check_wordboundary(common);
- }
-if (common->anynewline != NULL)
- {
- set_jumps(common->anynewline, LABEL());
- check_anynewline(common);
- }
-if (common->hspace != NULL)
- {
- set_jumps(common->hspace, LABEL());
- check_hspace(common);
- }
-if (common->vspace != NULL)
- {
- set_jumps(common->vspace, LABEL());
- check_vspace(common);
- }
-if (common->casefulcmp != NULL)
- {
- set_jumps(common->casefulcmp, LABEL());
- do_casefulcmp(common);
- }
-if (common->caselesscmp != NULL)
- {
- set_jumps(common->caselesscmp, LABEL());
- do_caselesscmp(common);
- }
-#ifdef SUPPORT_UTF
-if (common->utfreadchar != NULL)
- {
- set_jumps(common->utfreadchar, LABEL());
- do_utfreadchar(common);
- }
-#ifdef COMPILE_PCRE8
-if (common->utfreadtype8 != NULL)
- {
- set_jumps(common->utfreadtype8, LABEL());
- do_utfreadtype8(common);
- }
-#endif
-#endif /* COMPILE_PCRE8 */
-#ifdef SUPPORT_UCP
-if (common->getunichartype != NULL)
- {
- set_jumps(common->getunichartype, LABEL());
- do_getunichartype(common);
- }
-if (common->getunichartype_2 != NULL)
- {
- set_jumps(common->getunichartype_2, LABEL());
- do_getunichartype_2(common);
- }
-if (common->getunicharscript != NULL)
- {
- set_jumps(common->getunicharscript, LABEL());
- do_getunicharscript(common);
- }
-#endif
-
-SLJIT_FREE(common->localptrs);
-executable_func = sljit_generate_code(compiler);
-executable_size = sljit_get_generated_code_size(compiler);
-sljit_free_compiler(compiler);
-if (executable_func == NULL)
- return;
-
-/* Reuse the function descriptor if possible. */
-if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
- functions = (executable_functions *)extra->executable_jit;
-else
- {
- functions = SLJIT_MALLOC(sizeof(executable_functions));
- if (functions == NULL)
- {
- /* This case is highly unlikely since we just recently
- freed a lot of memory. Although not impossible. */
- sljit_free_code(executable_func);
- return;
- }
- memset(functions, 0, sizeof(executable_functions));
- extra->executable_jit = functions;
- extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
- }
-
-functions->executable_funcs[mode] = executable_func;
-functions->executable_sizes[mode] = executable_size;
-}
-
-static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
-{
-union {
- void* executable_func;
- jit_function call_executable_func;
-} convert_executable_func;
-pcre_uint8 local_area[LOCAL_SPACE_SIZE];
-struct sljit_stack local_stack;
-
-local_stack.top = (sljit_w)&local_area;
-local_stack.base = local_stack.top;
-local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
-local_stack.max_limit = local_stack.limit;
-arguments->stack = &local_stack;
-convert_executable_func.executable_func = executable_func;
-return convert_executable_func.call_executable_func(arguments);
-}
-
-int
-PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
- int length, int start_offset, int options, int *offsets, int offsetcount)
-{
-executable_functions *functions = (executable_functions *)extra_data->executable_jit;
-union {
- void* executable_func;
- jit_function call_executable_func;
-} convert_executable_func;
-jit_arguments arguments;
-int maxoffsetcount;
-int retval;
-int mode = JIT_COMPILE;
-
-if ((options & PCRE_PARTIAL_HARD) != 0)
- mode = JIT_PARTIAL_HARD_COMPILE;
-else if ((options & PCRE_PARTIAL_SOFT) != 0)
- mode = JIT_PARTIAL_SOFT_COMPILE;
-
-if (functions->executable_funcs[mode] == NULL)
- return PCRE_ERROR_NULL;
-
-/* Sanity checks should be handled by pcre_exec. */
-arguments.stack = NULL;
-arguments.str = subject + start_offset;
-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.notbol = (options & PCRE_NOTBOL) != 0;
-arguments.noteol = (options & PCRE_NOTEOL) != 0;
-arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
-arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
-arguments.offsets = offsets;
-
-/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
-the output vector for storing captured strings, with the remainder used as
-workspace. We don't need the workspace here. For compatibility, we limit the
-number of captured strings in the same way as pcre_exec(), so that the user
-gets the same result with and without JIT. */
-
-if (offsetcount != 2)
- offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
-maxoffsetcount = (re->top_bracket + 1) * 2;
-if (offsetcount > maxoffsetcount)
- offsetcount = maxoffsetcount;
-arguments.offsetcount = offsetcount;
-
-if (functions->callback)
- arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
-else
- arguments.stack = (struct sljit_stack *)functions->userdata;
-
-if (arguments.stack == NULL)
- retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
-else
- {
- convert_executable_func.executable_func = functions->executable_funcs[mode];
- retval = convert_executable_func.call_executable_func(&arguments);
- }
-
-if (retval * 2 > offsetcount)
- retval = 0;
-if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = arguments.mark_ptr;
-
-return retval;
-}
-
-void
-PRIV(jit_free)(void *executable_funcs)
-{
-int i;
-executable_functions *functions = (executable_functions *)executable_funcs;
-for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
- {
- if (functions->executable_funcs[i] != NULL)
- sljit_free_code(functions->executable_funcs[i]);
- }
-SLJIT_FREE(functions);
-}
-
-int
-PRIV(jit_get_size)(void *executable_funcs)
-{
-int i;
-sljit_uw size = 0;
-sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
-for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
- size += executable_sizes[i];
-return (int)size;
-}
-
-const char*
-PRIV(jit_get_target)(void)
-{
-return sljit_get_platform_name();
-}
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL pcre_jit_stack *
-pcre_jit_stack_alloc(int startsize, int maxsize)
-#else
-PCRE_EXP_DECL pcre16_jit_stack *
-pcre16_jit_stack_alloc(int startsize, int maxsize)
-#endif
-{
-if (startsize < 1 || maxsize < 1)
- return NULL;
-if (startsize > maxsize)
- startsize = maxsize;
-startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
-maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
-return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
-}
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL void
-pcre_jit_stack_free(pcre_jit_stack *stack)
-#else
-PCRE_EXP_DECL void
-pcre16_jit_stack_free(pcre16_jit_stack *stack)
-#endif
-{
-sljit_free_stack((struct sljit_stack *)stack);
-}
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL void
-pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
-#else
-PCRE_EXP_DECL void
-pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
-#endif
-{
-executable_functions *functions;
-if (extra != NULL &&
- (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra->executable_jit != NULL)
- {
- functions = (executable_functions *)extra->executable_jit;
- functions->callback = callback;
- functions->userdata = userdata;
- }
-}
-
-#else /* SUPPORT_JIT */
-
-/* These are dummy functions to avoid linking errors when JIT support is not
-being compiled. */
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL pcre_jit_stack *
-pcre_jit_stack_alloc(int startsize, int maxsize)
-#else
-PCRE_EXP_DECL pcre16_jit_stack *
-pcre16_jit_stack_alloc(int startsize, int maxsize)
-#endif
-{
-(void)startsize;
-(void)maxsize;
-return NULL;
-}
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL void
-pcre_jit_stack_free(pcre_jit_stack *stack)
-#else
-PCRE_EXP_DECL void
-pcre16_jit_stack_free(pcre16_jit_stack *stack)
-#endif
-{
-(void)stack;
-}
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DECL void
-pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
-#else
-PCRE_EXP_DECL void
-pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
-#endif
-{
-(void)extra;
-(void)callback;
-(void)userdata;
-}
-
-#endif
-
-/* End of pcre_jit_compile.c */
diff --git a/glib/pcre/pcre_newline.c b/glib/pcre/pcre_newline.c
deleted file mode 100644
index ddd7708fa..000000000
--- a/glib/pcre/pcre_newline.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains internal functions for testing newlines when more than
-one kind of newline is to be recognized. When a newline is found, its length is
-returned. In principle, we could implement several newline "types", each
-referring to a different set of newline characters. At present, PCRE supports
-only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
-and NLTYPE_ANY. The full list of Unicode newline characters is taken from
-http://unicode.org/unicode/reports/tr18/. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-
-/*************************************************
-* Check for newline at given position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is less than the end of the
-string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- endptr pointer to the end of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
- BOOL utf)
-{
-int c;
-(void)utf;
-#ifdef SUPPORT_UTF
-if (utf)
- {
- GETCHAR(c, ptr);
- }
-else
-#endif /* SUPPORT_UTF */
- c = *ptr;
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case 0x000a: *lenptr = 1; return TRUE; /* LF */
- case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
- return TRUE; /* CR */
- default: return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
- case 0x000a: /* LF */
- case 0x000b: /* VT */
- case 0x000c: *lenptr = 1; return TRUE; /* FF */
- case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
- return TRUE; /* CR */
-#ifdef COMPILE_PCRE8
- case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
-#else
- case 0x0085: /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 1; return TRUE; /* PS */
-#endif /* COMPILE_PCRE8 */
- default: return FALSE;
- }
-}
-
-
-
-/*************************************************
-* Check for newline at previous position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is greater than the start of
-the string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- startptr pointer to the start of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
- BOOL utf)
-{
-int c;
-(void)utf;
-ptr--;
-#ifdef SUPPORT_UTF
-if (utf)
- {
- BACKCHAR(ptr);
- GETCHAR(c, ptr);
- }
-else
-#endif /* SUPPORT_UTF */
- c = *ptr;
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
- return TRUE; /* LF */
- case 0x000d: *lenptr = 1; return TRUE; /* CR */
- default: return FALSE;
- }
-
-else switch(c)
- {
- case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
- return TRUE; /* LF */
- case 0x000b: /* VT */
- case 0x000c: /* FF */
- case 0x000d: *lenptr = 1; return TRUE; /* CR */
-#ifdef COMPILE_PCRE8
- case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
-#else
- case 0x0085: /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 1; return TRUE; /* PS */
-#endif /* COMPILE_PCRE8 */
- default: return FALSE;
- }
-}
-
-/* End of pcre_newline.c */
diff --git a/glib/pcre/pcre_ord2utf8.c b/glib/pcre/pcre_ord2utf8.c
deleted file mode 100644
index 71fd587e0..000000000
--- a/glib/pcre/pcre_ord2utf8.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This file contains a private PCRE function that converts an ordinal
-character value into a UTF8 string. */
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Convert character value to UTF-8 *
-*************************************************/
-
-/* This function takes an integer value in the range 0 - 0x10ffff
-and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
-
-Arguments:
- cvalue the character value
- buffer pointer to buffer for result - at least 6 pcre_uchars long
-
-Returns: number of characters placed in the buffer
-*/
-
-int
-PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
-{
-#ifdef SUPPORT_UTF
-
-int i, j;
-
-/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
-Should never happen in practice. */
-if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
- cvalue = 0xfffe;
-
-for (i = 0; i < PRIV(utf8_table1_size); i++)
- if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
-buffer += i;
-for (j = i; j > 0; j--)
- {
- *buffer-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*buffer = PRIV(utf8_table2)[i] | cvalue;
-return i + 1;
-
-#else
-
-(void)(cvalue); /* Keep compiler happy; this function won't ever be */
-(void)(buffer); /* called when SUPPORT_UTF is not defined. */
-return 0;
-
-#endif
-}
-
-/* End of pcre_ord2utf8.c */
diff --git a/glib/pcre/pcre_string_utils.c b/glib/pcre/pcre_string_utils.c
deleted file mode 100644
index 38cc2f958..000000000
--- a/glib/pcre/pcre_string_utils.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that is used to match an extended
-class. It is used by both pcre_exec() and pcre_def_exec(). */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-#ifndef COMPILE_PCRE8
-
-/*************************************************
-* Compare string utilities *
-*************************************************/
-
-/* The following two functions compares two strings. Basically an strcmp
-for non 8 bit characters.
-
-Arguments:
- str1 first string
- str2 second string
-
-Returns: 0 if both string are equal (like strcmp), 1 otherwise
-*/
-
-int
-PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2)
-{
-pcre_uchar c1;
-pcre_uchar c2;
-
-while (*str1 != '\0' || *str2 != '\0')
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2)
- return ((c1 > c2) << 1) - 1;
- }
-/* Both length and characters must be equal. */
-return 0;
-}
-
-int
-PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2)
-{
-const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
-pcre_uchar c1;
-pcre_uchar c2;
-
-while (*str1 != '\0' || *ustr2 != '\0')
- {
- c1 = *str1++;
- c2 = (pcre_uchar)*ustr2++;
- if (c1 != c2)
- return ((c1 > c2) << 1) - 1;
- }
-/* Both length and characters must be equal. */
-return 0;
-}
-
-/* The following two functions compares two, fixed length
-strings. Basically an strncmp for non 8 bit characters.
-
-Arguments:
- str1 first string
- str2 second string
- num size of the string
-
-Returns: 0 if both string are equal (like strcmp), 1 otherwise
-*/
-
-int
-PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num)
-{
-pcre_uchar c1;
-pcre_uchar c2;
-
-while (num-- > 0)
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2)
- return ((c1 > c2) << 1) - 1;
- }
-/* Both length and characters must be equal. */
-return 0;
-}
-
-int
-PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num)
-{
-const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
-pcre_uchar c1;
-pcre_uchar c2;
-
-while (num-- > 0)
- {
- c1 = *str1++;
- c2 = (pcre_uchar)*ustr2++;
- if (c1 != c2)
- return ((c1 > c2) << 1) - 1;
- }
-/* Both length and characters must be equal. */
-return 0;
-}
-
-/* The following function returns with the length of
-a zero terminated string. Basically an strlen for non 8 bit characters.
-
-Arguments:
- str string
-
-Returns: length of the string
-*/
-
-unsigned int
-PRIV(strlen_uc)(const pcre_uchar *str)
-{
-unsigned int len = 0;
-while (*str++ != 0)
- len++;
-return len;
-}
-
-#endif /* COMPILE_PCRE8 */
-
-/* End of pcre_string_utils.c */
diff --git a/glib/pcre/pcre_study.c b/glib/pcre/pcre_study.c
deleted file mode 100644
index ee0930718..000000000
--- a/glib/pcre/pcre_study.c
+++ /dev/null
@@ -1,1532 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_study(), along with local
-supporting functions. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-#define SET_BIT(c) start_bits[c/8] |= (1 << (c&7))
-
-/* Returns from set_start_bits() */
-
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
-
-
-
-/*************************************************
-* Find the minimum subject length for a group *
-*************************************************/
-
-/* Scan a parenthesized group and compute the minimum length of subject that
-is needed to match it. This is a lower bound; it does not mean there is a
-string of that length that matches. In UTF8 mode, the result is in characters
-rather than bytes.
-
-Arguments:
- code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern
- options the compiling options
- int RECURSE depth
-
-Returns: the minimum length
- -1 if \C in UTF-8 mode or (*ACCEPT) was encountered
- -2 internal error (missing capturing bracket)
- -3 internal error (opcode not listed)
-*/
-
-static int
-find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
- int recurse_depth)
-{
-int length = -1;
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-BOOL had_recurse = FALSE;
-int branchlength = 0;
-pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
-
-if (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
- {
- int d, min;
- pcre_uchar *cs, *ce;
- int op = *cc;
-
- switch (op)
- {
- case OP_COND:
- case OP_SCOND:
-
- /* If there is only one branch in a condition, the implied branch has zero
- length, so we don't add anything. This covers the DEFINE "condition"
- automatically. */
-
- cs = cc + GET(cc, 1);
- if (*cs != OP_ALT)
- {
- cc = cs + 1 + LINK_SIZE;
- break;
- }
-
- /* Otherwise we can fall through and treat it the same as any other
- subpattern. */
-
- case OP_CBRA:
- case OP_SCBRA:
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_ONCE:
- case OP_ONCE_NC:
- d = find_minlength(cc, startcode, options, recurse_depth);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* ACCEPT makes things far too complicated; we have to give up. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- return -1;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is END it's
- the end of the outer call. All can be handled by the same code. If an
- ACCEPT was previously encountered, use the length that was in force at that
- time, and pass back the shortest ACCEPT length. */
-
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_END:
- if (length < 0 || (!had_recurse && branchlength < length))
- length = branchlength;
- if (op != OP_ALT) return length;
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- had_recurse = FALSE;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
-
- /* Skip over things that don't match chars */
-
- case OP_REVERSE:
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- case OP_CALLOUT:
- case OP_SOD:
- case OP_SOM:
- case OP_EOD:
- case OP_EODN:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Skip over a subpattern that has a {0} or {0,x} quantifier */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- case OP_SKIPZERO:
- cc += PRIV(OP_lengths)[*cc];
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Handle literal characters and + repetitions */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- branchlength++;
- cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- need to skip over a multibyte character in UTF8 mode. */
-
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
- break;
-
- /* Handle single-char non-literal matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_EXTUNI:
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- branchlength++;
- cc++;
- break;
-
- /* "Any newline" might match two characters, but it also might match just
- one. */
-
- case OP_ANYNL:
- branchlength += 1;
- cc++;
- break;
-
- /* The single-byte matcher means we can't proceed in UTF-8 mode. (In
- non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever
- appear, but leave the code, just in case.) */
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UTF
- if (utf) return -1;
-#endif
- branchlength++;
- cc++;
- break;
-
- /* For repeated character types, we have to test for \p and \P, which have
- an extra two bytes of parameters. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSQUERY:
- if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* Check a class for variable quantification */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
- /* Fall through */
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- cc += PRIV(OP_lengths)[OP_CLASS];
-
- switch (*cc)
- {
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- branchlength++;
- /* Fall through */
-
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- branchlength += GET2(cc,1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- branchlength++;
- break;
- }
- break;
-
- /* Backreferences and subroutine calls are treated in the same way: we find
- the minimum length for the subpattern. A recursion, however, causes an
- a flag to be set that causes the length of this branch to be ignored. The
- logic is that a recursion can only make sense if there is another
- alternation that stops the recursing. That will provide the minimum length
- (when no recursion happens). A backreference within the group that it is
- referencing behaves in the same way.
-
- If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket
- matches an empty string (by default it causes a matching failure), so in
- that case we must set the minimum length to zero. */
-
- case OP_REF:
- case OP_REFI:
- if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
- {
- ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
- if (cs == NULL) return -2;
- do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce)
- {
- d = 0;
- had_recurse = TRUE;
- }
- else
- {
- d = find_minlength(cs, startcode, options, recurse_depth);
- }
- }
- else d = 0;
- cc += 1 + IMM2_SIZE;
-
- /* Handle repeated back references */
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- min = 0;
- cc++;
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- min = 1;
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(cc, 1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- min = 1;
- break;
- }
-
- branchlength += min * d;
- break;
-
- /* We can easily detect direct recursion, but not mutual recursion. This is
- caught by a recursion depth count. */
-
- case OP_RECURSE:
- cs = ce = (pcre_uchar *)startcode + GET(cc, 1);
- do ce += GET(ce, 1); while (*ce == OP_ALT);
- if ((cc > cs && cc < ce) || recurse_depth > 10)
- had_recurse = TRUE;
- else
- {
- branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- /* Anything else does not or need not match a character. We can get the
- item's length from the table, but for those that can match zero occurrences
- of a character, we must take special action for UTF-8 characters. As it
- happens, the "NOT" versions of these opcodes are used at present only for
- ASCII characters, so they could be omitted from this list. However, in
- future that may change, so we include them here so as not to leave a
- gotcha for a future maintainer. */
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
-
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
-
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
-
- cc += PRIV(OP_lengths)[op];
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- /* Skip these, but we need to add in the name length. */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += PRIV(OP_lengths)[op] + cc[1];
- break;
-
- /* The remaining opcodes are just skipped over. */
-
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_FAIL:
- case OP_PRUNE:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_THEN:
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* This should not occur: we list all opcodes explicitly so that when
- new ones get added they are properly considered. */
-
- default:
- return -3;
- }
- }
-/* Control never gets here */
-}
-
-
-
-/*************************************************
-* Set a bit and maybe its alternate case *
-*************************************************/
-
-/* Given a character, set its first byte's bit in the table, and also the
-corresponding bit for the other version of a letter if we are caseless. In
-UTF-8 mode, for characters greater than 127, we can only do the caseless thing
-when Unicode property support is available.
-
-Arguments:
- start_bits points to the bit map
- p points to the character
- caseless the caseless flag
- cd the block with char table pointers
- utf TRUE for UTF-8 / UTF-16 mode
-
-Returns: pointer after the character
-*/
-
-static const pcre_uchar *
-set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
- compile_data *cd, BOOL utf)
-{
-unsigned int c = *p;
-
-#ifdef COMPILE_PCRE8
-SET_BIT(c);
-
-#ifdef SUPPORT_UTF
-if (utf && c > 127)
- {
- GETCHARINC(c, p);
-#ifdef SUPPORT_UCP
- if (caseless)
- {
- pcre_uchar buff[6];
- c = UCD_OTHERCASE(c);
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
-#endif
- return p;
- }
-#endif
-
-/* Not UTF-8 mode, or character is less than 127. */
-
-if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
-return p + 1;
-#endif
-
-#ifdef COMPILE_PCRE16
-if (c > 0xff)
- {
- c = 0xff;
- caseless = FALSE;
- }
-SET_BIT(c);
-
-#ifdef SUPPORT_UTF
-if (utf && c > 127)
- {
- GETCHARINC(c, p);
-#ifdef SUPPORT_UCP
- if (caseless)
- {
- c = UCD_OTHERCASE(c);
- if (c > 0xff)
- c = 0xff;
- SET_BIT(c);
- }
-#endif
- return p;
- }
-#endif
-
-if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
-return p + 1;
-#endif
-}
-
-
-
-/*************************************************
-* Set bits for a positive character type *
-*************************************************/
-
-/* This function sets starting bits for a character type. In UTF-8 mode, we can
-only do a direct setting for bytes less than 128, as otherwise there can be
-confusion with bytes in the middle of UTF-8 characters. In a "traditional"
-environment, the tables will only recognize ASCII characters anyway, but in at
-least one Windows environment, some higher bytes bits were set in the tables.
-So we deal with that case by considering the UTF-8 encoding.
-
-Arguments:
- start_bits the starting bitmap
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
- cd the block with char table pointers
-
-Returns: nothing
-*/
-
-static void
-set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
- compile_data *cd)
-{
-int c;
-for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (table_limit == 32) return;
-for (c = 128; c < 256; c++)
- {
- if ((cd->cbits[c/8] & (1 << (c&7))) != 0)
- {
- pcre_uchar buff[6];
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
- }
-#endif
-}
-
-
-/*************************************************
-* Set bits for a negative character type *
-*************************************************/
-
-/* This function sets starting bits for a negative character type such as \D.
-In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
-otherwise there can be confusion with bytes in the middle of UTF-8 characters.
-Unlike in the positive case, where we can set appropriate starting bits for
-specific high-valued UTF-8 characters, in this case we have to set the bits for
-all high-valued characters. The lowest is 0xc2, but we overkill by starting at
-0xc0 (192) for simplicity.
-
-Arguments:
- start_bits the starting bitmap
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
- cd the block with char table pointers
-
-Returns: nothing
-*/
-
-static void
-set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
- compile_data *cd)
-{
-int c;
-for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
-#endif
-}
-
-
-
-/*************************************************
-* Create bitmap of starting bytes *
-*************************************************/
-
-/* This function scans a compiled unanchored expression recursively and
-attempts to build a bitmap of the set of possible starting bytes. As time goes
-by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
-useful for parenthesized groups in patterns such as (a*)b where the group
-provides some optional starting bytes but scanning must continue at the outer
-level to find at least one mandatory byte. At the outermost level, this
-function fails unless the result is SSB_DONE.
-
-Arguments:
- code points to an expression
- start_bits points to a 32-byte table, initialized to 0
- utf TRUE if in UTF-8 / UTF-16 mode
- cd the block with char table pointers
-
-Returns: SSB_FAIL => Failed to find any starting bytes
- SSB_DONE => Found mandatory starting bytes
- SSB_CONTINUE => Found optional starting bytes
- SSB_UNKNOWN => Hit an unrecognized opcode
-*/
-
-static int
-set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
- compile_data *cd)
-{
-int c;
-int yield = SSB_DONE;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-int table_limit = utf? 16:32;
-#else
-int table_limit = 32;
-#endif
-
-#if 0
-/* ========================================================================= */
-/* The following comment and code was inserted in January 1999. In May 2006,
-when it was observed to cause compiler warnings about unused values, I took it
-out again. If anybody is still using OS/2, they will have to put it back
-manually. */
-
-/* This next statement and the later reference to dummy are here in order to
-trick the optimizer of the IBM C compiler for OS/2 into generating correct
-code. Apparently IBM isn't going to fix the problem, and we would rather not
-disable optimization (in this module it actually makes a big difference, and
-the pcre module can use all the optimization it can get). */
-
-volatile int dummy;
-/* ========================================================================= */
-#endif
-
-do
- {
- BOOL try_next = TRUE;
- const pcre_uchar *tcode = code + 1 + LINK_SIZE;
-
- if (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
-
- while (try_next) /* Loop for items in this branch */
- {
- int rc;
-
- switch(*tcode)
- {
- /* If we reach something we don't understand, it means a new opcode has
- been created that hasn't been added to this code. Hopefully this problem
- will be discovered during testing. */
-
- default:
- return SSB_UNKNOWN;
-
- /* Fail for a valid opcode that implies no starting bits. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- case OP_ALLANY:
- case OP_ANY:
- case OP_ANYBYTE:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_COND:
- case OP_CREF:
- case OP_DEF:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_END:
- case OP_EOD:
- case OP_EODN:
- case OP_EXTUNI:
- case OP_FAIL:
- case OP_MARK:
- case OP_NCREF:
- case OP_NOT:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_NOTI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_NOTPROP:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_NOT_HSPACE:
- case OP_NOT_VSPACE:
- case OP_NRREF:
- case OP_PROP:
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_RECURSE:
- case OP_REF:
- case OP_REFI:
- case OP_REVERSE:
- case OP_RREF:
- case OP_SCOND:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_SKIP_ARG:
- case OP_SOD:
- case OP_SOM:
- case OP_THEN:
- case OP_THEN_ARG:
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
-#endif
- return SSB_FAIL;
-
- /* We can ignore word boundary tests. */
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- tcode++;
- break;
-
- /* If we hit a bracket or a positive lookahead assertion, recurse to set
- bits from within the subpattern. If it can't find anything, we have to
- give up. If it finds some mandatory character(s), we are done for this
- branch. Otherwise, carry on scanning after the subpattern. */
-
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_ASSERT:
- rc = set_start_bits(tcode, start_bits, utf, cd);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
- if (rc == SSB_DONE) try_next = FALSE; else
- {
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- }
- break;
-
- /* If we hit ALT or KET, it means we haven't found anything mandatory in
- this branch, though we might have found something optional. For ALT, we
- continue with the next alternative, but we have to arrange that the final
- result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
- return SSB_CONTINUE: if this is the top level, that indicates failure,
- but after a nested subpattern, it causes scanning to continue. */
-
- case OP_ALT:
- yield = SSB_CONTINUE;
- try_next = FALSE;
- break;
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- return SSB_CONTINUE;
-
- /* Skip over callout */
-
- case OP_CALLOUT:
- tcode += 2 + 2*LINK_SIZE;
- break;
-
- /* Skip over lookbehind and negative lookahead assertions */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* BRAZERO does the bracket, but carries on. */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- rc = set_start_bits(++tcode, start_bits, utf, cd);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
-/* =========================================================================
- See the comment at the head of this function concerning the next line,
- which was an old fudge for the benefit of OS/2.
- dummy = 1;
- ========================================================================= */
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* SKIPZERO skips the bracket. */
-
- case OP_SKIPZERO:
- tcode++;
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* Single-char * or ? sets the bit and tries the next item */
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
- break;
-
- case OP_STARI:
- case OP_MINSTARI:
- case OP_POSSTARI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
- break;
-
- /* Single-char upto sets the bit and tries the next */
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf);
- break;
-
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_POSUPTOI:
- tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf);
- break;
-
- /* At least one single char sets the bit and stops */
-
- case OP_EXACT:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
- try_next = FALSE;
- break;
-
- case OP_EXACTI:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
- try_next = FALSE;
- break;
-
- /* Special spacing and line-terminating items. These recognize specific
- lists of characters. The difference between VSPACE and ANYNL is that the
- latter can match the two-character CRLF sequence, but that is not
- relevant for finding the first character, so their code here is
- identical. */
-
- case OP_HSPACE:
- SET_BIT(0x09);
- SET_BIT(0x20);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
-#endif
-#ifdef COMPILE_PCRE16
- SET_BIT(0xA0);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- else
-#endif /* SUPPORT_UTF */
- {
- SET_BIT(0xA0);
-#ifdef COMPILE_PCRE16
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- try_next = FALSE;
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(0x0A);
- SET_BIT(0x0B);
- SET_BIT(0x0C);
- SET_BIT(0x0D);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+0085 */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
-#endif
-#ifdef COMPILE_PCRE16
- SET_BIT(0x85);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- else
-#endif /* SUPPORT_UTF */
- {
- SET_BIT(0x85);
-#ifdef COMPILE_PCRE16
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- try_next = FALSE;
- break;
-
- /* Single character types set the bits and stop. Note that if PCRE_UCP
- is set, we do not see these op codes because \d etc are converted to
- properties. Therefore, these apply in the case when only characters less
- than 256 are recognized to match the types. */
-
- case OP_NOT_DIGIT:
- set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
- try_next = FALSE;
- break;
-
- case OP_DIGIT:
- set_type_bits(start_bits, cbit_digit, table_limit, cd);
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- ensure it is set as not whitespace. */
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] |= 0x08;
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- not set it from the table. */
-
- case OP_WHITESPACE:
- c = start_bits[1]; /* Save in case it was already set */
- set_type_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] = (start_bits[1] & ~0x08) | c;
- try_next = FALSE;
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(start_bits, cbit_word, table_limit, cd);
- try_next = FALSE;
- break;
-
- case OP_WORDCHAR:
- set_type_bits(start_bits, cbit_word, table_limit, cd);
- try_next = FALSE;
- break;
-
- /* One or more character type fudges the pointer and restarts, knowing
- it will hit a single character type and stop there. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- tcode++;
- break;
-
- case OP_TYPEEXACT:
- tcode += 1 + IMM2_SIZE;
- break;
-
- /* Zero or more repeats of character types set the bits and then
- try again. */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- tcode += IMM2_SIZE; /* Fall through */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- switch(tcode[1])
- {
- default:
- case OP_ANY:
- case OP_ALLANY:
- return SSB_FAIL;
-
- case OP_HSPACE:
- SET_BIT(0x09);
- SET_BIT(0x20);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
-#endif
-#ifdef COMPILE_PCRE16
- SET_BIT(0xA0);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- else
-#endif /* SUPPORT_UTF */
- SET_BIT(0xA0);
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(0x0A);
- SET_BIT(0x0B);
- SET_BIT(0x0C);
- SET_BIT(0x0D);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+0085 */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
-#endif
-#ifdef COMPILE_PCRE16
- SET_BIT(0x85);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- else
-#endif /* SUPPORT_UTF */
- SET_BIT(0x85);
- break;
-
- case OP_NOT_DIGIT:
- set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
- break;
-
- case OP_DIGIT:
- set_type_bits(start_bits, cbit_digit, table_limit, cd);
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- ensure it gets set as not whitespace. */
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] |= 0x08;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- avoid setting it. */
-
- case OP_WHITESPACE:
- c = start_bits[1]; /* Save in case it was already set */
- set_type_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] = (start_bits[1] & ~0x08) | c;
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(start_bits, cbit_word, table_limit, cd);
- break;
-
- case OP_WORDCHAR:
- set_type_bits(start_bits, cbit_word, table_limit, cd);
- break;
- }
-
- tcode += 2;
- break;
-
- /* Character class where all the information is in a bit map: set the
- bits and either carry on or not, according to the repeat count. If it was
- a negative class, and we are operating with UTF-8 characters, any byte
- with a value >= 0xc4 is a potentially valid starter because it starts a
- character with a value > 255. */
-
- case OP_NCLASS:
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- if (utf)
- {
- start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
- memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
- }
-#endif
-#ifdef COMPILE_PCRE16
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- /* Fall through */
-
- case OP_CLASS:
- {
- pcre_uint8 *map;
- tcode++;
- map = (pcre_uint8 *)tcode;
-
- /* In UTF-8 mode, the bits in a bit map correspond to character
- values, not to byte values. However, the bit map we are constructing is
- for byte values. So we have to do a conversion for characters whose
- value is > 127. In fact, there are only two possible starting bytes for
- characters in the range 128 - 255. */
-
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- if (utf)
- {
- for (c = 0; c < 16; c++) start_bits[c] |= map[c];
- for (c = 128; c < 256; c++)
- {
- if ((map[c/8] && (1 << (c&7))) != 0)
- {
- int d = (c >> 6) | 0xc0; /* Set bit for this starter */
- start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
- c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
- }
- }
- }
- else
-#endif
- {
- /* In non-UTF-8 mode, the two bit maps are completely compatible. */
- for (c = 0; c < 32; c++) start_bits[c] |= map[c];
- }
-
- /* Advance past the bit map, and act on what follows. For a zero
- minimum repeat, continue; otherwise stop processing. */
-
- tcode += 32 / sizeof(pcre_uchar);
- switch (*tcode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- tcode++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
- else try_next = FALSE;
- break;
-
- default:
- try_next = FALSE;
- break;
- }
- }
- break; /* End of bitmap class handling */
-
- } /* End of switch */
- } /* End of try_next loop */
-
- code += GET(code, 1); /* Advance to next branch */
- }
-while (*code == OP_ALT);
-return yield;
-}
-
-
-
-
-
-/*************************************************
-* Study a compiled expression *
-*************************************************/
-
-/* This function is handed a compiled expression that it must study to produce
-information that will speed up the matching. It returns a pcre[16]_extra block
-which then gets handed back to pcre_exec().
-
-Arguments:
- re points to the compiled expression
- options contains option bits
- errorptr points to where to place error messages;
- set NULL unless error
-
-Returns: pointer to a pcre[16]_extra block, with study_data filled in and
- the appropriate flags set;
- NULL on error or if no optimization possible
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
-pcre_study(const pcre *external_re, int options, const char **errorptr)
-#else
-PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
-pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
-#endif
-{
-int min;
-BOOL bits_set = FALSE;
-pcre_uint8 start_bits[32];
-PUBL(extra) *extra = NULL;
-pcre_study_data *study;
-const pcre_uint8 *tables;
-pcre_uchar *code;
-compile_data compile_block;
-const REAL_PCRE *re = (const REAL_PCRE *)external_re;
-
-*errorptr = NULL;
-
-if (re == NULL || re->magic_number != MAGIC_NUMBER)
- {
- *errorptr = "argument is not a compiled regular expression";
- return NULL;
- }
-
-if ((re->flags & PCRE_MODE) == 0)
- {
-#ifdef COMPILE_PCRE8
- *errorptr = "argument is compiled in 16 bit mode";
-#else
- *errorptr = "argument is compiled in 8 bit mode";
-#endif
- return NULL;
- }
-
-if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
- {
- *errorptr = "unknown or incorrect option bit(s) set";
- return NULL;
- }
-
-code = (pcre_uchar *)re + re->name_table_offset +
- (re->name_count * re->name_entry_size);
-
-/* For an anchored pattern, or an unanchored pattern that has a first char, or
-a multiline pattern that matches only at "line starts", there is no point in
-seeking a list of starting bytes. */
-
-if ((re->options & PCRE_ANCHORED) == 0 &&
- (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
- {
- int rc;
-
- /* Set the character tables in the block that is passed around */
-
- tables = re->tables;
-
-#ifdef COMPILE_PCRE8
- if (tables == NULL)
- (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-#else
- if (tables == NULL)
- (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-#endif
-
- compile_block.lcc = tables + lcc_offset;
- compile_block.fcc = tables + fcc_offset;
- compile_block.cbits = tables + cbits_offset;
- compile_block.ctypes = tables + ctypes_offset;
-
- /* See if we can find a fixed set of initial characters for the pattern. */
-
- memset(start_bits, 0, 32 * sizeof(pcre_uint8));
- rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0,
- &compile_block);
- bits_set = rc == SSB_DONE;
- if (rc == SSB_UNKNOWN)
- {
- *errorptr = "internal error: opcode not recognized";
- return NULL;
- }
- }
-
-/* Find the minimum length of subject string. */
-
-switch(min = find_minlength(code, code, re->options, 0))
- {
- case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
- case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
- default: break;
- }
-
-/* If a set of starting bytes has been identified, or if the minimum length is
-greater than zero, or if JIT optimization has been requested, get a
-pcre[16]_extra block and a pcre_study_data block. The study data is put in the
-latter, which is pointed to by the former, which may also get additional data
-set later by the calling program. At the moment, the size of pcre_study_data
-is fixed. We nevertheless save it in a field for returning via the
-pcre_fullinfo() function so that if it becomes variable in the future,
-we don't have to change that code. */
-
-if (bits_set || min > 0
-#ifdef SUPPORT_JIT
- || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
- | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0
-#endif
- )
- {
- extra = (PUBL(extra) *)(PUBL(malloc))
- (sizeof(PUBL(extra)) + sizeof(pcre_study_data));
- if (extra == NULL)
- {
- *errorptr = "failed to get memory";
- return NULL;
- }
-
- study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra)));
- extra->flags = PCRE_EXTRA_STUDY_DATA;
- extra->study_data = study;
-
- study->size = sizeof(pcre_study_data);
- study->flags = 0;
-
- /* Set the start bits always, to avoid unset memory errors if the
- study data is written to a file, but set the flag only if any of the bits
- are set, to save time looking when none are. */
-
- if (bits_set)
- {
- study->flags |= PCRE_STUDY_MAPPED;
- memcpy(study->start_bits, start_bits, sizeof(start_bits));
- }
- else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8));
-
-#ifdef PCRE_DEBUG
- if (bits_set)
- {
- pcre_uint8 *ptr = start_bits;
- int i;
-
- printf("Start bits:\n");
- for (i = 0; i < 32; i++)
- printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n");
- }
-#endif
-
- /* Always set the minlength value in the block, because the JIT compiler
- makes use of it. However, don't set the bit unless the length is greater than
- zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time
- checking the zero case. */
-
- if (min > 0)
- {
- study->flags |= PCRE_STUDY_MINLEN;
- study->minlength = min;
- }
- else study->minlength = 0;
-
- /* If JIT support was compiled and requested, attempt the JIT compilation.
- If no starting bytes were found, and the minimum length is zero, and JIT
- compilation fails, abandon the extra block and return NULL. */
-
-#ifdef SUPPORT_JIT
- extra->executable_jit = NULL;
- if ((options & PCRE_STUDY_JIT_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_COMPILE);
- if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE);
- if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE);
-
- if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
- {
-#ifdef COMPILE_PCRE8
- pcre_free_study(extra);
-#endif
-#ifdef COMPILE_PCRE16
- pcre16_free_study(extra);
-#endif
- extra = NULL;
- }
-#endif
- }
-
-return extra;
-}
-
-
-/*************************************************
-* Free the study data *
-*************************************************/
-
-/* This function frees the memory that was obtained by pcre_study().
-
-Argument: a pointer to the pcre[16]_extra block
-Returns: nothing
-*/
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN void
-pcre_free_study(pcre_extra *extra)
-#else
-PCRE_EXP_DEFN void
-pcre16_free_study(pcre16_extra *extra)
-#endif
-{
-if (extra == NULL)
- return;
-#ifdef SUPPORT_JIT
-if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra->executable_jit != NULL)
- PRIV(jit_free)(extra->executable_jit);
-#endif
-PUBL(free)(extra);
-}
-
-/* End of pcre_study.c */
diff --git a/glib/pcre/pcre_tables.c b/glib/pcre/pcre_tables.c
deleted file mode 100644
index abcc96ef4..000000000
--- a/glib/pcre/pcre_tables.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef PCRE_INCLUDED
-
-/* This module contains some fixed tables that are used by more than one of the
-PCRE code modules. The tables are also #included by the pcretest program, which
-uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
-clashes with the library. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-#endif /* PCRE_INCLUDED */
-
-/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
-the definition is next to the definition of the opcodes in pcre_internal.h. */
-
-const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
-
-
-
-/*************************************************
-* Tables for UTF-8 support *
-*************************************************/
-
-/* These are the breakpoints for different numbers of bytes in a UTF-8
-character. */
-
-#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
- || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
-
-/* These tables are also required by pcretest in 16 bit mode. */
-
-const int PRIV(utf8_table1)[] =
- { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
-
-const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
-
-/* These are the indicator bits and the mask for the data bits to set in the
-first byte of a character, indexed by the number of additional bytes. */
-
-const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-/* Table of the number of extra bytes, indexed by the first byte masked with
-0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
-
-const pcre_uint8 PRIV(utf8_table4)[] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
-
-#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
-
-#ifdef SUPPORT_UTF
-
-/* Table to translate from particular type value to the general value. */
-
-const int PRIV(ucp_gentype)[] = {
- ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
- ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
- ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
- ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
- ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
- ucp_P, ucp_P, /* Ps, Po */
- ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
- ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
-};
-
-#ifdef SUPPORT_JIT
-/* This table reverses PRIV(ucp_gentype). We can save the cost
-of a memory load. */
-
-const int PRIV(ucp_typerange)[] = {
- ucp_Cc, ucp_Cs,
- ucp_Ll, ucp_Lu,
- ucp_Mc, ucp_Mn,
- ucp_Nd, ucp_No,
- ucp_Pc, ucp_Ps,
- ucp_Sc, ucp_So,
- ucp_Zl, ucp_Zs,
-};
-#endif /* SUPPORT_JIT */
-
-/* The pcre_utt[] table below translates Unicode property names into type and
-code values. It is searched by binary chop, so must be in collating sequence of
-name. Originally, the table contained pointers to the name strings in the first
-field of each entry. However, that leads to a large number of relocations when
-a shared library is dynamically loaded. A significant reduction is made by
-putting all the names into a single, large string and then using offsets in the
-table itself. Maintenance is more error-prone, but frequent changes to this
-data are unlikely.
-
-July 2008: There is now a script called maint/GenerateUtt.py that can be used
-to generate this data automatically instead of maintaining it by hand.
-
-The script was updated in March 2009 to generate a new EBCDIC-compliant
-version. Like all other character and string literals that are compared against
-the regular expression pattern, we must use STR_ macros instead of literal
-strings to make sure that UTF-8 support works on EBCDIC platforms. */
-
-#define STRING_Any0 STR_A STR_n STR_y "\0"
-#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
-#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
-#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
-#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
-#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
-#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
-#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
-#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
-#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
-#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
-#define STRING_C0 STR_C "\0"
-#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
-#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
-#define STRING_Cc0 STR_C STR_c "\0"
-#define STRING_Cf0 STR_C STR_f "\0"
-#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
-#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
-#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
-#define STRING_Cn0 STR_C STR_n "\0"
-#define STRING_Co0 STR_C STR_o "\0"
-#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
-#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
-#define STRING_Cs0 STR_C STR_s "\0"
-#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
-#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
-#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
-#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
-#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
-#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
-#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
-#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
-#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
-#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
-#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
-#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
-#define STRING_Han0 STR_H STR_a STR_n "\0"
-#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
-#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
-#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
-#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
-#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
-#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
-#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
-#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
-#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
-#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
-#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
-#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
-#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
-#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
-#define STRING_L0 STR_L "\0"
-#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
-#define STRING_Lao0 STR_L STR_a STR_o "\0"
-#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
-#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
-#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
-#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
-#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
-#define STRING_Ll0 STR_L STR_l "\0"
-#define STRING_Lm0 STR_L STR_m "\0"
-#define STRING_Lo0 STR_L STR_o "\0"
-#define STRING_Lt0 STR_L STR_t "\0"
-#define STRING_Lu0 STR_L STR_u "\0"
-#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
-#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
-#define STRING_M0 STR_M "\0"
-#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
-#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
-#define STRING_Mc0 STR_M STR_c "\0"
-#define STRING_Me0 STR_M STR_e "\0"
-#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
-#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"
-#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0"
-#define STRING_Mn0 STR_M STR_n "\0"
-#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
-#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
-#define STRING_N0 STR_N "\0"
-#define STRING_Nd0 STR_N STR_d "\0"
-#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
-#define STRING_Nko0 STR_N STR_k STR_o "\0"
-#define STRING_Nl0 STR_N STR_l "\0"
-#define STRING_No0 STR_N STR_o "\0"
-#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
-#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
-#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
-#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
-#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
-#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
-#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
-#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
-#define STRING_P0 STR_P "\0"
-#define STRING_Pc0 STR_P STR_c "\0"
-#define STRING_Pd0 STR_P STR_d "\0"
-#define STRING_Pe0 STR_P STR_e "\0"
-#define STRING_Pf0 STR_P STR_f "\0"
-#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
-#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
-#define STRING_Pi0 STR_P STR_i "\0"
-#define STRING_Po0 STR_P STR_o "\0"
-#define STRING_Ps0 STR_P STR_s "\0"
-#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
-#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
-#define STRING_S0 STR_S "\0"
-#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
-#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
-#define STRING_Sc0 STR_S STR_c "\0"
-#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"
-#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
-#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
-#define STRING_Sk0 STR_S STR_k "\0"
-#define STRING_Sm0 STR_S STR_m "\0"
-#define STRING_So0 STR_S STR_o "\0"
-#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0"
-#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
-#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
-#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
-#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
-#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
-#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
-#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
-#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0"
-#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
-#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
-#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
-#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
-#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
-#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
-#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
-#define STRING_Vai0 STR_V STR_a STR_i "\0"
-#define STRING_Xan0 STR_X STR_a STR_n "\0"
-#define STRING_Xps0 STR_X STR_p STR_s "\0"
-#define STRING_Xsp0 STR_X STR_s STR_p "\0"
-#define STRING_Xwd0 STR_X STR_w STR_d "\0"
-#define STRING_Yi0 STR_Y STR_i "\0"
-#define STRING_Z0 STR_Z "\0"
-#define STRING_Zl0 STR_Z STR_l "\0"
-#define STRING_Zp0 STR_Z STR_p "\0"
-#define STRING_Zs0 STR_Z STR_s "\0"
-
-const char PRIV(utt_names)[] =
- STRING_Any0
- STRING_Arabic0
- STRING_Armenian0
- STRING_Avestan0
- STRING_Balinese0
- STRING_Bamum0
- STRING_Batak0
- STRING_Bengali0
- STRING_Bopomofo0
- STRING_Brahmi0
- STRING_Braille0
- STRING_Buginese0
- STRING_Buhid0
- STRING_C0
- STRING_Canadian_Aboriginal0
- STRING_Carian0
- STRING_Cc0
- STRING_Cf0
- STRING_Chakma0
- STRING_Cham0
- STRING_Cherokee0
- STRING_Cn0
- STRING_Co0
- STRING_Common0
- STRING_Coptic0
- STRING_Cs0
- STRING_Cuneiform0
- STRING_Cypriot0
- STRING_Cyrillic0
- STRING_Deseret0
- STRING_Devanagari0
- STRING_Egyptian_Hieroglyphs0
- STRING_Ethiopic0
- STRING_Georgian0
- STRING_Glagolitic0
- STRING_Gothic0
- STRING_Greek0
- STRING_Gujarati0
- STRING_Gurmukhi0
- STRING_Han0
- STRING_Hangul0
- STRING_Hanunoo0
- STRING_Hebrew0
- STRING_Hiragana0
- STRING_Imperial_Aramaic0
- STRING_Inherited0
- STRING_Inscriptional_Pahlavi0
- STRING_Inscriptional_Parthian0
- STRING_Javanese0
- STRING_Kaithi0
- STRING_Kannada0
- STRING_Katakana0
- STRING_Kayah_Li0
- STRING_Kharoshthi0
- STRING_Khmer0
- STRING_L0
- STRING_L_AMPERSAND0
- STRING_Lao0
- STRING_Latin0
- STRING_Lepcha0
- STRING_Limbu0
- STRING_Linear_B0
- STRING_Lisu0
- STRING_Ll0
- STRING_Lm0
- STRING_Lo0
- STRING_Lt0
- STRING_Lu0
- STRING_Lycian0
- STRING_Lydian0
- STRING_M0
- STRING_Malayalam0
- STRING_Mandaic0
- STRING_Mc0
- STRING_Me0
- STRING_Meetei_Mayek0
- STRING_Meroitic_Cursive0
- STRING_Meroitic_Hieroglyphs0
- STRING_Miao0
- STRING_Mn0
- STRING_Mongolian0
- STRING_Myanmar0
- STRING_N0
- STRING_Nd0
- STRING_New_Tai_Lue0
- STRING_Nko0
- STRING_Nl0
- STRING_No0
- STRING_Ogham0
- STRING_Ol_Chiki0
- STRING_Old_Italic0
- STRING_Old_Persian0
- STRING_Old_South_Arabian0
- STRING_Old_Turkic0
- STRING_Oriya0
- STRING_Osmanya0
- STRING_P0
- STRING_Pc0
- STRING_Pd0
- STRING_Pe0
- STRING_Pf0
- STRING_Phags_Pa0
- STRING_Phoenician0
- STRING_Pi0
- STRING_Po0
- STRING_Ps0
- STRING_Rejang0
- STRING_Runic0
- STRING_S0
- STRING_Samaritan0
- STRING_Saurashtra0
- STRING_Sc0
- STRING_Sharada0
- STRING_Shavian0
- STRING_Sinhala0
- STRING_Sk0
- STRING_Sm0
- STRING_So0
- STRING_Sora_Sompeng0
- STRING_Sundanese0
- STRING_Syloti_Nagri0
- STRING_Syriac0
- STRING_Tagalog0
- STRING_Tagbanwa0
- STRING_Tai_Le0
- STRING_Tai_Tham0
- STRING_Tai_Viet0
- STRING_Takri0
- STRING_Tamil0
- STRING_Telugu0
- STRING_Thaana0
- STRING_Thai0
- STRING_Tibetan0
- STRING_Tifinagh0
- STRING_Ugaritic0
- STRING_Vai0
- STRING_Xan0
- STRING_Xps0
- STRING_Xsp0
- STRING_Xwd0
- STRING_Yi0
- STRING_Z0
- STRING_Zl0
- STRING_Zp0
- STRING_Zs0;
-
-const ucp_type_table PRIV(utt)[] = {
- { 0, PT_ANY, 0 },
- { 4, PT_SC, ucp_Arabic },
- { 11, PT_SC, ucp_Armenian },
- { 20, PT_SC, ucp_Avestan },
- { 28, PT_SC, ucp_Balinese },
- { 37, PT_SC, ucp_Bamum },
- { 43, PT_SC, ucp_Batak },
- { 49, PT_SC, ucp_Bengali },
- { 57, PT_SC, ucp_Bopomofo },
- { 66, PT_SC, ucp_Brahmi },
- { 73, PT_SC, ucp_Braille },
- { 81, PT_SC, ucp_Buginese },
- { 90, PT_SC, ucp_Buhid },
- { 96, PT_GC, ucp_C },
- { 98, PT_SC, ucp_Canadian_Aboriginal },
- { 118, PT_SC, ucp_Carian },
- { 125, PT_PC, ucp_Cc },
- { 128, PT_PC, ucp_Cf },
- { 131, PT_SC, ucp_Chakma },
- { 138, PT_SC, ucp_Cham },
- { 143, PT_SC, ucp_Cherokee },
- { 152, PT_PC, ucp_Cn },
- { 155, PT_PC, ucp_Co },
- { 158, PT_SC, ucp_Common },
- { 165, PT_SC, ucp_Coptic },
- { 172, PT_PC, ucp_Cs },
- { 175, PT_SC, ucp_Cuneiform },
- { 185, PT_SC, ucp_Cypriot },
- { 193, PT_SC, ucp_Cyrillic },
- { 202, PT_SC, ucp_Deseret },
- { 210, PT_SC, ucp_Devanagari },
- { 221, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 242, PT_SC, ucp_Ethiopic },
- { 251, PT_SC, ucp_Georgian },
- { 260, PT_SC, ucp_Glagolitic },
- { 271, PT_SC, ucp_Gothic },
- { 278, PT_SC, ucp_Greek },
- { 284, PT_SC, ucp_Gujarati },
- { 293, PT_SC, ucp_Gurmukhi },
- { 302, PT_SC, ucp_Han },
- { 306, PT_SC, ucp_Hangul },
- { 313, PT_SC, ucp_Hanunoo },
- { 321, PT_SC, ucp_Hebrew },
- { 328, PT_SC, ucp_Hiragana },
- { 337, PT_SC, ucp_Imperial_Aramaic },
- { 354, PT_SC, ucp_Inherited },
- { 364, PT_SC, ucp_Inscriptional_Pahlavi },
- { 386, PT_SC, ucp_Inscriptional_Parthian },
- { 409, PT_SC, ucp_Javanese },
- { 418, PT_SC, ucp_Kaithi },
- { 425, PT_SC, ucp_Kannada },
- { 433, PT_SC, ucp_Katakana },
- { 442, PT_SC, ucp_Kayah_Li },
- { 451, PT_SC, ucp_Kharoshthi },
- { 462, PT_SC, ucp_Khmer },
- { 468, PT_GC, ucp_L },
- { 470, PT_LAMP, 0 },
- { 473, PT_SC, ucp_Lao },
- { 477, PT_SC, ucp_Latin },
- { 483, PT_SC, ucp_Lepcha },
- { 490, PT_SC, ucp_Limbu },
- { 496, PT_SC, ucp_Linear_B },
- { 505, PT_SC, ucp_Lisu },
- { 510, PT_PC, ucp_Ll },
- { 513, PT_PC, ucp_Lm },
- { 516, PT_PC, ucp_Lo },
- { 519, PT_PC, ucp_Lt },
- { 522, PT_PC, ucp_Lu },
- { 525, PT_SC, ucp_Lycian },
- { 532, PT_SC, ucp_Lydian },
- { 539, PT_GC, ucp_M },
- { 541, PT_SC, ucp_Malayalam },
- { 551, PT_SC, ucp_Mandaic },
- { 559, PT_PC, ucp_Mc },
- { 562, PT_PC, ucp_Me },
- { 565, PT_SC, ucp_Meetei_Mayek },
- { 578, PT_SC, ucp_Meroitic_Cursive },
- { 595, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 616, PT_SC, ucp_Miao },
- { 621, PT_PC, ucp_Mn },
- { 624, PT_SC, ucp_Mongolian },
- { 634, PT_SC, ucp_Myanmar },
- { 642, PT_GC, ucp_N },
- { 644, PT_PC, ucp_Nd },
- { 647, PT_SC, ucp_New_Tai_Lue },
- { 659, PT_SC, ucp_Nko },
- { 663, PT_PC, ucp_Nl },
- { 666, PT_PC, ucp_No },
- { 669, PT_SC, ucp_Ogham },
- { 675, PT_SC, ucp_Ol_Chiki },
- { 684, PT_SC, ucp_Old_Italic },
- { 695, PT_SC, ucp_Old_Persian },
- { 707, PT_SC, ucp_Old_South_Arabian },
- { 725, PT_SC, ucp_Old_Turkic },
- { 736, PT_SC, ucp_Oriya },
- { 742, PT_SC, ucp_Osmanya },
- { 750, PT_GC, ucp_P },
- { 752, PT_PC, ucp_Pc },
- { 755, PT_PC, ucp_Pd },
- { 758, PT_PC, ucp_Pe },
- { 761, PT_PC, ucp_Pf },
- { 764, PT_SC, ucp_Phags_Pa },
- { 773, PT_SC, ucp_Phoenician },
- { 784, PT_PC, ucp_Pi },
- { 787, PT_PC, ucp_Po },
- { 790, PT_PC, ucp_Ps },
- { 793, PT_SC, ucp_Rejang },
- { 800, PT_SC, ucp_Runic },
- { 806, PT_GC, ucp_S },
- { 808, PT_SC, ucp_Samaritan },
- { 818, PT_SC, ucp_Saurashtra },
- { 829, PT_PC, ucp_Sc },
- { 832, PT_SC, ucp_Sharada },
- { 840, PT_SC, ucp_Shavian },
- { 848, PT_SC, ucp_Sinhala },
- { 856, PT_PC, ucp_Sk },
- { 859, PT_PC, ucp_Sm },
- { 862, PT_PC, ucp_So },
- { 865, PT_SC, ucp_Sora_Sompeng },
- { 878, PT_SC, ucp_Sundanese },
- { 888, PT_SC, ucp_Syloti_Nagri },
- { 901, PT_SC, ucp_Syriac },
- { 908, PT_SC, ucp_Tagalog },
- { 916, PT_SC, ucp_Tagbanwa },
- { 925, PT_SC, ucp_Tai_Le },
- { 932, PT_SC, ucp_Tai_Tham },
- { 941, PT_SC, ucp_Tai_Viet },
- { 950, PT_SC, ucp_Takri },
- { 956, PT_SC, ucp_Tamil },
- { 962, PT_SC, ucp_Telugu },
- { 969, PT_SC, ucp_Thaana },
- { 976, PT_SC, ucp_Thai },
- { 981, PT_SC, ucp_Tibetan },
- { 989, PT_SC, ucp_Tifinagh },
- { 998, PT_SC, ucp_Ugaritic },
- { 1007, PT_SC, ucp_Vai },
- { 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 }
-};
-
-const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
-
-unsigned int
-_pcre_ucp_othercase(const unsigned int c)
-{
- unsigned int oc = NOTACHAR;
-
- if ((oc = g_unichar_toupper(c)) != c)
- return oc;
- if ((oc = g_unichar_tolower(c)) != c)
- return oc;
-
- return c;
-}
-
-#endif /* SUPPORT_UTF */
-
-/* End of pcre_tables.c */
diff --git a/glib/pcre/pcre_valid_utf8.c b/glib/pcre/pcre_valid_utf8.c
deleted file mode 100644
index cecaf347f..000000000
--- a/glib/pcre/pcre_valid_utf8.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function for validating UTF-8 character
-strings. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Validate a UTF-8 string *
-*************************************************/
-
-/* This function is called (optionally) at the start of compile or match, to
-check that a supposed UTF-8 string is actually valid. The early check means
-that subsequent code can assume it is dealing with a valid string. The check
-can be turned off for maximum performance, but the consequences of supplying an
-invalid string are then undefined.
-
-Originally, this function checked according to RFC 2279, allowing for values in
-the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
-the canonical format. Once somebody had pointed out RFC 3629 to me (it
-obsoletes 2279), additional restrictions were applied. The values are now
-limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
-subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
-characters is still checked.
-
-From release 8.13 more information about the details of the error are passed
-back in the returned value:
-
-PCRE_UTF8_ERR0 No error
-PCRE_UTF8_ERR1 Missing 1 byte at the end of the string
-PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string
-PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string
-PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string
-PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string
-PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80
-PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80
-PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629
-PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629
-PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
-PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted
-PCRE_UTF8_ERR15 Overlong 2-byte sequence
-PCRE_UTF8_ERR16 Overlong 3-byte sequence
-PCRE_UTF8_ERR17 Overlong 4-byte sequence
-PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
-PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
-PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
-PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
-
-Arguments:
- string points to the string
- length length of string, or -1 if the string is zero-terminated
- errp pointer to an error position offset variable
-
-Returns: = 0 if the string is a valid UTF-8 string
- > 0 otherwise, setting the offset of the bad character
-*/
-
-int
-PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
-{
-#ifdef SUPPORT_UTF
-PCRE_PUCHAR p;
-
-if (length < 0)
- {
- for (p = string; *p != 0; p++);
- length = (int)(p - string);
- }
-
-for (p = string; length-- > 0; p++)
- {
- int ab, c, d;
-
- c = *p;
- if (c < 128) continue; /* ASCII character */
-
- if (c < 0xc0) /* Isolated 10xx xxxx byte */
- {
- *erroroffset = (int)(p - string);
- return PCRE_UTF8_ERR20;
- }
-
- if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
- {
- *erroroffset = (int)(p - string);
- return PCRE_UTF8_ERR21;
- }
-
- ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
- if (length < ab)
- {
- *erroroffset = (int)(p - string); /* Missing bytes */
- return ab - length; /* Codes ERR1 to ERR5 */
- }
- length -= ab; /* Length remaining */
-
- /* Check top bits in the second byte */
-
- if (((d = *(++p)) & 0xc0) != 0x80)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE_UTF8_ERR6;
- }
-
- /* For each length, check that the remaining bytes start with the 0x80 bit
- set and not the 0x40 bit. Then check for an overlong sequence, and for the
- excluded range 0xd800 to 0xdfff. */
-
- switch (ab)
- {
- /* 2-byte character. No further bytes to check for 0x80. Check first byte
- for for xx00 000x (overlong sequence). */
-
- case 1: if ((c & 0x3e) == 0)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE_UTF8_ERR15;
- }
- break;
-
- /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
- for 1110 0000, xx0x xxxx (overlong sequence) or
- 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
-
- case 2:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if (c == 0xe0 && (d & 0x20) == 0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR16;
- }
- if (c == 0xed && d >= 0xa0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR14;
- }
- break;
-
- /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
- bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
- character greater than 0x0010ffff (f4 8f bf bf) */
-
- case 3:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if (c == 0xf0 && (d & 0x30) == 0)
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR17;
- }
- if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR13;
- }
- break;
-
- /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
- rejected by the length test below. However, we do the appropriate tests
- here so that overlong sequences get diagnosed, and also in case there is
- ever an option for handling these larger code points. */
-
- /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
- 1111 1000, xx00 0xxx */
-
- case 4:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR9;
- }
- if (c == 0xf8 && (d & 0x38) == 0)
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR18;
- }
- break;
-
- /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
- 1111 1100, xx00 00xx. */
-
- case 5:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR9;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE_UTF8_ERR10;
- }
- if (c == 0xfc && (d & 0x3c) == 0)
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE_UTF8_ERR19;
- }
- break;
- }
-
- /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
- excluded by RFC 3629. The pointer p is currently at the last byte of the
- character. */
-
- if (ab > 3)
- {
- *erroroffset = (int)(p - string) - ab;
- return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
- }
- }
-
-#else /* SUPPORT_UTF */
-(void)(string); /* Keep picky compilers happy */
-(void)(length);
-#endif
-
-return PCRE_UTF8_ERR0; /* This indicates success */
-}
-
-/* End of pcre_valid_utf8.c */
diff --git a/glib/pcre/pcre_version.c b/glib/pcre/pcre_version.c
deleted file mode 100644
index 3dd60a5bc..000000000
--- a/glib/pcre/pcre_version.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_version(), which returns a
-string that identifies the PCRE version that is in use. */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return version string *
-*************************************************/
-
-/* These macros are the standard way of turning unquoted text into C strings.
-They allow macros like PCRE_MAJOR to be defined without quotes, which is
-convenient for user programs that want to test its value. */
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* A problem turned up with PCRE_PRERELEASE, which is defined empty for
-production releases. Originally, it was used naively in this code:
-
- return XSTRING(PCRE_MAJOR)
- "." XSTRING(PCRE_MINOR)
- XSTRING(PCRE_PRERELEASE)
- " " XSTRING(PCRE_DATE);
-
-However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of
-STRING(). The C standard states: "If (before argument substitution) any
-argument consists of no preprocessing tokens, the behavior is undefined." It
-turns out the gcc treats this case as a single empty string - which is what we
-really want - but Visual C grumbles about the lack of an argument for the
-macro. Unfortunately, both are within their rights. To cope with both ways of
-handling this, I had resort to some messy hackery that does a test at run time.
-I could find no way of detecting that a macro is defined as an empty string at
-pre-processor time. This hack uses a standard trick for avoiding calling
-the STRING macro with an empty argument when doing the test. */
-
-#ifdef COMPILE_PCRE8
-PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
-pcre_version(void)
-#else
-PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
-pcre16_version(void)
-#endif
-{
-return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
- XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
- XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
-}
-
-/* End of pcre_version.c */
diff --git a/glib/pcre/pcre_xclass.c b/glib/pcre/pcre_xclass.c
deleted file mode 100644
index 89ad09f54..000000000
--- a/glib/pcre/pcre_xclass.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that is used to match an extended
-class. It is used by both pcre_exec() and pcre_def_exec(). */
-
-
-#include "config.h"
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Match character against an XCLASS *
-*************************************************/
-
-/* This function is called to match a character against an extended class that
-might contain values > 255 and/or Unicode properties.
-
-Arguments:
- c the character
- data points to the flag byte of the XCLASS data
-
-Returns: TRUE if character matches, else FALSE
-*/
-
-BOOL
-PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
-{
-int t;
-BOOL negated = (*data & XCL_NOT) != 0;
-
-(void)utf;
-#ifdef COMPILE_PCRE8
-/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
-utf = TRUE;
-#endif
-
-/* Character values < 256 are matched against a bitmap, if one is present. If
-not, we still carry on, because there may be ranges that start below 256 in the
-additional data. */
-
-if (c < 256)
- {
- if ((*data & XCL_MAP) != 0 &&
- (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
- return !negated; /* char found */
- }
-
-/* First skip the bit map if present. Then match against the list of Unicode
-properties or large chars or ranges that end with a large char. We won't ever
-encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
-
-if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
-
-while ((t = *data++) != XCL_END)
- {
- int x, y;
- if (t == XCL_SINGLE)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- }
- else
-#endif
- x = *data++;
- if (c == x) return !negated;
- }
- else if (t == XCL_RANGE)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- GETCHARINC(y, data); /* macro generates multiple statements */
- }
- else
-#endif
- {
- x = *data++;
- y = *data++;
- }
- if (c >= x && c <= y) return !negated;
- }
-
-#ifdef SUPPORT_UCP
- else /* XCL_PROP & XCL_NOTPROP */
- {
- const pcre_uint8 chartype = UCD_CHARTYPE(c);
-
- switch(*data)
- {
- case PT_ANY:
- if (t == XCL_PROP) return !negated;
- break;
-
- case PT_LAMP:
- if ((chartype == ucp_Lu || chartype == ucp_Ll ||
- chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_GC:
- if ((data[1] == PRIV(ucp_gentype)[chartype]) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PC:
- if ((data[1] == chartype) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_SC:
- if ((data[1] == UCD_SCRIPT(c)) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_SPACE: /* Perl space */
- if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
- PRIV(ucp_gentype)[chartype] == ucp_N || c == CHAR_UNDERSCORE)
- == (t == XCL_PROP))
- return !negated;
- break;
-
- /* This should never occur, but compilers may mutter if there is no
- default. */
-
- default:
- return FALSE;
- }
-
- data += 2;
- }
-#endif /* SUPPORT_UCP */
- }
-
-return negated; /* char did not match */
-}
-
-/* End of pcre_xclass.c */
diff --git a/glib/pcre/ucp.h b/glib/pcre/ucp.h
deleted file mode 100644
index f1c14be5d..000000000
--- a/glib/pcre/ucp.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*************************************************
-* Unicode Property Table handler *
-*************************************************/
-
-#ifndef _UCP_H
-#define _UCP_H
-
-/* This file contains definitions of the property values that are returned by
-the UCD access macros. New values that are added for new releases of Unicode
-should always be at the end of each enum, for backwards compatibility. */
-
-/* These are the general character categories. */
-#ifdef GLIB_COMPILATION
-#include "gunicode.h"
-#else
-#include <glib.h>
-#endif
-
-enum {
- ucp_C, /* Other */
- ucp_L, /* Letter */
- ucp_M, /* Mark */
- ucp_N, /* Number */
- ucp_P, /* Punctuation */
- ucp_S, /* Symbol */
- ucp_Z /* Separator */
-};
-
-/* These are the particular character types. */
-
-enum {
- ucp_Cc = G_UNICODE_CONTROL, /* Control */
- ucp_Cf = G_UNICODE_FORMAT, /* Format */
- ucp_Cn = G_UNICODE_UNASSIGNED, /* Unassigned */
- ucp_Co = G_UNICODE_PRIVATE_USE, /* Private use */
- ucp_Cs = G_UNICODE_SURROGATE, /* Surrogate */
- ucp_Ll = G_UNICODE_LOWERCASE_LETTER, /* Lower case letter */
- ucp_Lm = G_UNICODE_MODIFIER_LETTER, /* Modifier letter */
- ucp_Lo = G_UNICODE_OTHER_LETTER, /* Other letter */
- ucp_Lt = G_UNICODE_TITLECASE_LETTER, /* Title case letter */
- ucp_Lu = G_UNICODE_UPPERCASE_LETTER, /* Upper case letter */
- ucp_Mc = G_UNICODE_SPACING_MARK, /* Spacing mark */
- ucp_Me = G_UNICODE_ENCLOSING_MARK, /* Enclosing mark */
- ucp_Mn = G_UNICODE_NON_SPACING_MARK, /* Non-spacing mark */
- ucp_Nd = G_UNICODE_DECIMAL_NUMBER, /* Decimal number */
- ucp_Nl = G_UNICODE_LETTER_NUMBER, /* Letter number */
- ucp_No = G_UNICODE_OTHER_NUMBER, /* Other number */
- ucp_Pc = G_UNICODE_CONNECT_PUNCTUATION, /* Connector punctuation */
- ucp_Pd = G_UNICODE_DASH_PUNCTUATION, /* Dash punctuation */
- ucp_Pe = G_UNICODE_CLOSE_PUNCTUATION, /* Close punctuation */
- ucp_Pf = G_UNICODE_FINAL_PUNCTUATION, /* Final punctuation */
- ucp_Pi = G_UNICODE_INITIAL_PUNCTUATION, /* Initial punctuation */
- ucp_Po = G_UNICODE_OTHER_PUNCTUATION, /* Other punctuation */
- ucp_Ps = G_UNICODE_OPEN_PUNCTUATION, /* Open punctuation */
- ucp_Sc = G_UNICODE_CURRENCY_SYMBOL, /* Currency symbol */
- ucp_Sk = G_UNICODE_MODIFIER_SYMBOL, /* Modifier symbol */
- ucp_Sm = G_UNICODE_MATH_SYMBOL, /* Mathematical symbol */
- ucp_So = G_UNICODE_OTHER_SYMBOL, /* Other symbol */
- ucp_Zl = G_UNICODE_LINE_SEPARATOR, /* Line separator */
- ucp_Zp = G_UNICODE_PARAGRAPH_SEPARATOR, /* Paragraph separator */
- ucp_Zs = G_UNICODE_SPACE_SEPARATOR /* Space separator */
-};
-
-/* These are the script identifications. */
-
-enum {
- ucp_Common = G_UNICODE_SCRIPT_COMMON,
- ucp_Inherited = G_UNICODE_SCRIPT_INHERITED,
-
- ucp_Arabic = G_UNICODE_SCRIPT_ARABIC,
- ucp_Armenian = G_UNICODE_SCRIPT_ARMENIAN,
- ucp_Bengali = G_UNICODE_SCRIPT_BENGALI,
- ucp_Bopomofo = G_UNICODE_SCRIPT_BOPOMOFO,
- ucp_Braille = G_UNICODE_SCRIPT_BRAILLE,
- ucp_Buginese = G_UNICODE_SCRIPT_BUGINESE,
- ucp_Buhid = G_UNICODE_SCRIPT_BUHID,
- ucp_Canadian_Aboriginal = G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
- ucp_Cherokee = G_UNICODE_SCRIPT_CHEROKEE,
- ucp_Coptic = G_UNICODE_SCRIPT_COPTIC,
- ucp_Cypriot = G_UNICODE_SCRIPT_CYPRIOT,
- ucp_Cyrillic = G_UNICODE_SCRIPT_CYRILLIC,
- ucp_Deseret = G_UNICODE_SCRIPT_DESERET,
- ucp_Devanagari = G_UNICODE_SCRIPT_DEVANAGARI,
- ucp_Ethiopic = G_UNICODE_SCRIPT_ETHIOPIC,
- ucp_Georgian = G_UNICODE_SCRIPT_GEORGIAN,
- ucp_Glagolitic = G_UNICODE_SCRIPT_GLAGOLITIC,
- ucp_Gothic = G_UNICODE_SCRIPT_GOTHIC,
- ucp_Greek = G_UNICODE_SCRIPT_GREEK,
- ucp_Gujarati = G_UNICODE_SCRIPT_GUJARATI,
- ucp_Gurmukhi = G_UNICODE_SCRIPT_GURMUKHI,
- ucp_Han = G_UNICODE_SCRIPT_HAN,
- ucp_Hangul = G_UNICODE_SCRIPT_HANGUL,
- ucp_Hanunoo = G_UNICODE_SCRIPT_HANUNOO,
- ucp_Hebrew = G_UNICODE_SCRIPT_HEBREW,
- ucp_Hiragana = G_UNICODE_SCRIPT_HIRAGANA,
- ucp_Kannada = G_UNICODE_SCRIPT_KANNADA,
- ucp_Katakana = G_UNICODE_SCRIPT_KATAKANA,
- ucp_Kharoshthi = G_UNICODE_SCRIPT_KHAROSHTHI,
- ucp_Khmer = G_UNICODE_SCRIPT_KHMER,
- ucp_Lao = G_UNICODE_SCRIPT_LAO,
- ucp_Latin = G_UNICODE_SCRIPT_LATIN,
- ucp_Limbu = G_UNICODE_SCRIPT_LIMBU,
- ucp_Linear_B = G_UNICODE_SCRIPT_LINEAR_B,
- ucp_Malayalam = G_UNICODE_SCRIPT_MALAYALAM,
- ucp_Mongolian = G_UNICODE_SCRIPT_MONGOLIAN,
- ucp_Myanmar = G_UNICODE_SCRIPT_MYANMAR,
- ucp_New_Tai_Lue = G_UNICODE_SCRIPT_NEW_TAI_LUE,
- ucp_Ogham = G_UNICODE_SCRIPT_OGHAM,
- ucp_Old_Italic = G_UNICODE_SCRIPT_OLD_ITALIC,
- ucp_Old_Persian = G_UNICODE_SCRIPT_OLD_PERSIAN,
- ucp_Oriya = G_UNICODE_SCRIPT_ORIYA,
- ucp_Osmanya = G_UNICODE_SCRIPT_OSMANYA,
- ucp_Runic = G_UNICODE_SCRIPT_RUNIC,
- ucp_Shavian = G_UNICODE_SCRIPT_SHAVIAN,
- ucp_Sinhala = G_UNICODE_SCRIPT_SINHALA,
- ucp_Syloti_Nagri = G_UNICODE_SCRIPT_SYLOTI_NAGRI,
- ucp_Syriac = G_UNICODE_SCRIPT_SYRIAC,
- ucp_Tagalog = G_UNICODE_SCRIPT_TAGALOG,
- ucp_Tagbanwa = G_UNICODE_SCRIPT_TAGBANWA,
- ucp_Tai_Le = G_UNICODE_SCRIPT_TAI_LE,
- ucp_Tamil = G_UNICODE_SCRIPT_TAMIL,
- ucp_Telugu = G_UNICODE_SCRIPT_TELUGU,
- ucp_Thaana = G_UNICODE_SCRIPT_THAANA,
- ucp_Thai = G_UNICODE_SCRIPT_THAI,
- ucp_Tibetan = G_UNICODE_SCRIPT_TIBETAN,
- ucp_Tifinagh = G_UNICODE_SCRIPT_TIFINAGH,
- ucp_Ugaritic = G_UNICODE_SCRIPT_UGARITIC,
- ucp_Yi = G_UNICODE_SCRIPT_YI,
- /* New for Unicode 5.0: */
- ucp_Balinese = G_UNICODE_SCRIPT_BALINESE,
- ucp_Cuneiform = G_UNICODE_SCRIPT_CUNEIFORM,
- ucp_Nko = G_UNICODE_SCRIPT_NKO,
- ucp_Phags_Pa = G_UNICODE_SCRIPT_PHAGS_PA,
- ucp_Phoenician = G_UNICODE_SCRIPT_PHOENICIAN,
- /* New for Unicode 5.1: */
- ucp_Carian = G_UNICODE_SCRIPT_CARIAN,
- ucp_Cham = G_UNICODE_SCRIPT_CHAM,
- ucp_Kayah_Li = G_UNICODE_SCRIPT_KAYAH_LI,
- ucp_Lepcha = G_UNICODE_SCRIPT_LEPCHA,
- ucp_Lycian = G_UNICODE_SCRIPT_LYCIAN,
- ucp_Lydian = G_UNICODE_SCRIPT_LYDIAN,
- ucp_Ol_Chiki = G_UNICODE_SCRIPT_OL_CHIKI,
- ucp_Rejang = G_UNICODE_SCRIPT_REJANG,
- ucp_Saurashtra = G_UNICODE_SCRIPT_SAURASHTRA,
- ucp_Sundanese = G_UNICODE_SCRIPT_SUNDANESE,
- ucp_Vai = G_UNICODE_SCRIPT_VAI,
- /* New for Unicode 5.2: */
- ucp_Avestan = G_UNICODE_SCRIPT_AVESTAN,
- ucp_Bamum = G_UNICODE_SCRIPT_BAMUM,
- ucp_Egyptian_Hieroglyphs = G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS,
- ucp_Imperial_Aramaic = G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC,
- ucp_Inscriptional_Pahlavi = G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI,
- ucp_Inscriptional_Parthian = G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN,
- ucp_Javanese = G_UNICODE_SCRIPT_JAVANESE,
- ucp_Kaithi = G_UNICODE_SCRIPT_KAITHI,
- ucp_Lisu = G_UNICODE_SCRIPT_LISU,
- ucp_Meetei_Mayek = G_UNICODE_SCRIPT_MEETEI_MAYEK,
- ucp_Old_South_Arabian = G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN,
- ucp_Old_Turkic = G_UNICODE_SCRIPT_OLD_TURKIC,
- ucp_Samaritan = G_UNICODE_SCRIPT_SAMARITAN,
- ucp_Tai_Tham = G_UNICODE_SCRIPT_TAI_THAM,
- ucp_Tai_Viet = G_UNICODE_SCRIPT_TAI_VIET,
- /* New for Unicode 6.0.0: */
- ucp_Batak = G_UNICODE_SCRIPT_BATAK,
- ucp_Brahmi = G_UNICODE_SCRIPT_BRAHMI,
- ucp_Mandaic = G_UNICODE_SCRIPT_MANDAIC,
- /* New for Unicode 6.1.0: */
- ucp_Chakma = G_UNICODE_SCRIPT_CHAKMA,
- ucp_Meroitic_Cursive = G_UNICODE_SCRIPT_MEROITIC_CURSIVE,
- ucp_Meroitic_Hieroglyphs = G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS,
- ucp_Miao = G_UNICODE_SCRIPT_MIAO,
- ucp_Sharada = G_UNICODE_SCRIPT_SHARADA,
- ucp_Sora_Sompeng = G_UNICODE_SCRIPT_SORA_SOMPENG,
- ucp_Takri = G_UNICODE_SCRIPT_TAKRI,
-};
-
-#endif
-
-/* End of ucp.h */
diff --git a/glib/tests/642026.c b/glib/tests/642026.c
index 26ab2ed06..aface4ea0 100644
--- a/glib/tests/642026.c
+++ b/glib/tests/642026.c
@@ -51,7 +51,7 @@ static gpointer thread_func (gpointer nil)
static void
testcase (void)
{
- g_test_bug ("642026");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642026");
mutex = g_mutex_new ();
cond = g_cond_new ();
@@ -86,7 +86,6 @@ main (int argc,
char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
g_test_add_func ("/glib/642026", testcase);
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index fef63f672..471f6171d 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -1991,8 +1991,6 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/");
-
/* array tests */
g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
g_test_add_func ("/array/ref-count", array_ref_count);
diff --git a/glib/tests/atomic.c b/glib/tests/atomic.c
index 14e6e454e..8bc100f4e 100644
--- a/glib/tests/atomic.c
+++ b/glib/tests/atomic.c
@@ -97,9 +97,12 @@ test_types (void)
/* Note that atomic variables should almost certainly not be marked as
* `volatile` — see http://isvolatileusefulwiththreads.in/c/. This test exists
* to make sure that we don’t warn when built against older third party code. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
g_atomic_pointer_set (&vp_str_vol, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
g_assert_true (res);
+#pragma GCC diagnostic pop
g_atomic_pointer_set (&ip, 0);
ip2 = g_atomic_pointer_get (&ip);
@@ -112,7 +115,7 @@ test_types (void)
vp2 = (gpointer) g_atomic_pointer_get (&gs);
gs2 = (gsize) vp2;
g_assert_cmpuint (gs2, ==, 0);
- res = g_atomic_pointer_compare_and_exchange (&gs, NULL, NULL);
+ res = g_atomic_pointer_compare_and_exchange (&gs, NULL, (gsize) NULL);
g_assert_true (res);
g_assert_cmpuint (gs, ==, 0);
gs2 = (gsize) g_atomic_pointer_add (&gs, 5);
@@ -129,7 +132,7 @@ test_types (void)
g_assert_cmpuint (gs, ==, 8);
g_assert_cmpint (g_atomic_int_get (csp), ==, s);
- g_assert_true (g_atomic_pointer_get (cspp) == csp);
+ g_assert_true (g_atomic_pointer_get ((const gint **) cspp) == csp);
/* repeat, without the macros */
#undef g_atomic_int_set
diff --git a/glib/tests/base64.c b/glib/tests/base64.c
index bf32ac629..93b1b1dd0 100644
--- a/glib/tests/base64.c
+++ b/glib/tests/base64.c
@@ -247,7 +247,7 @@ test_base64_encode_incremental_small_block (gconstpointer block_size_p)
gsize i;
struct MyRawData myraw;
- g_test_bug ("780066");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=780066");
generate_databuffer_for_base64 (&myraw);
@@ -492,7 +492,6 @@ main (int argc, char *argv[])
gint i;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/browse.cgi?product=");
for (i = 0; i < DATA_SIZE; i++)
data[i] = (guchar)i;
diff --git a/glib/tests/bookmarkfile.c b/glib/tests/bookmarkfile.c
index bc1a7a213..1700ad8b8 100644
--- a/glib/tests/bookmarkfile.c
+++ b/glib/tests/bookmarkfile.c
@@ -1,6 +1,7 @@
#undef G_DISABLE_ASSERT
#include <glib.h>
+#include <glib/gstdio.h>
#include <time.h>
#include <locale.h>
#include <string.h>
@@ -44,19 +45,25 @@ test_to_file (void)
gboolean res;
GError *error = NULL;
char *in, *out;
+ gchar *tmp_filename = NULL;
+ gint fd;
+
+ fd = g_file_open_tmp ("bookmarkfile-test-XXXXXX.xbel", &tmp_filename, NULL);
+ g_assert_cmpint (fd, >, -1);
+ g_close (fd, NULL);
bookmark = g_bookmark_file_new ();
- g_test_message ("Roundtrip from newly created bookmark file");
+ g_test_message ("Roundtrip from newly created bookmark file %s", tmp_filename);
g_bookmark_file_set_title (bookmark, "file:///tmp/schedule.ps", "schedule.ps");
g_bookmark_file_set_mime_type (bookmark, "file:///tmp/schedule.ps", "application/postscript");
g_bookmark_file_add_application (bookmark, "file:///tmp/schedule.ps", "ghostscript", "ghostscript %F");
- res = g_bookmark_file_to_file (bookmark, "out.xbel", &error);
+ res = g_bookmark_file_to_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
- res = g_bookmark_file_load_from_file (bookmark, "out.xbel", &error);
+ res = g_bookmark_file_load_from_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
@@ -70,7 +77,7 @@ test_to_file (void)
g_assert_cmpstr (out, ==, "application/postscript");
g_free (out);
- remove ("out.xbel");
+ remove (tmp_filename);
g_test_message ("Roundtrip from a valid bookmark file");
filename = g_test_get_filename (G_TEST_DIST, "bookmarks", "valid-01.xbel", NULL);
@@ -78,7 +85,7 @@ test_to_file (void)
g_assert_no_error (error);
g_assert_true (res);
- res = g_bookmark_file_to_file (bookmark, "out.xbel", &error);
+ res = g_bookmark_file_to_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
@@ -86,16 +93,17 @@ test_to_file (void)
g_assert_no_error (error);
g_assert_true (res);
- res = g_file_get_contents ("out.xbel", &out, NULL, &error);
+ res = g_file_get_contents (tmp_filename, &out, NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
- remove ("out.xbel");
+ remove (tmp_filename);
g_assert_cmpstr (in, ==, out);
g_free (in);
g_free (out);
g_bookmark_file_free (bookmark);
+ g_free (tmp_filename);
}
static void
diff --git a/glib/tests/bytes.c b/glib/tests/bytes.c
index cbc4d699c..8178bc2a8 100644
--- a/glib/tests/bytes.c
+++ b/glib/tests/bytes.c
@@ -38,8 +38,8 @@ test_new (void)
data = "test";
bytes = g_bytes_new (data, 4);
- g_assert (bytes != NULL);
- g_assert (g_bytes_get_data (bytes, &size) != data);
+ g_assert_nonnull (bytes);
+ g_assert_true (g_bytes_get_data (bytes, &size) != data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
@@ -56,8 +56,8 @@ test_new_take (void)
data = g_strdup ("test");
bytes = g_bytes_new_take (data, 4);
- g_assert (bytes != NULL);
- g_assert (g_bytes_get_data (bytes, &size) == data);
+ g_assert_nonnull (bytes);
+ g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
@@ -73,8 +73,8 @@ test_new_static (void)
data = "test";
bytes = g_bytes_new_static (data, 4);
- g_assert (bytes != NULL);
- g_assert (g_bytes_get_data (bytes, &size) == data);
+ g_assert_nonnull (bytes);
+ g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
@@ -91,8 +91,8 @@ test_new_from_bytes (void)
bytes = g_bytes_new (data, 14);
sub = g_bytes_new_from_bytes (bytes, 10, 4);
- g_assert (sub != NULL);
- g_assert (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
+ g_assert_nonnull (sub);
+ g_assert_true (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
g_bytes_unref (bytes);
g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4);
@@ -116,9 +116,9 @@ test_new_from_bytes_slice (void)
g_assert_cmpint (bytes3->ref_count, ==, 1);
g_assert_null (bytes->user_data);
- g_assert (bytes1->user_data == bytes);
- g_assert (bytes2->user_data == bytes);
- g_assert (bytes3->user_data == bytes);
+ g_assert_true (bytes1->user_data == bytes);
+ g_assert_true (bytes2->user_data == bytes);
+ g_assert_true (bytes3->user_data == bytes);
g_assert_cmpint (17, ==, g_bytes_get_size (bytes));
g_assert_cmpint (13, ==, g_bytes_get_size (bytes1));
@@ -145,7 +145,7 @@ test_new_from_bytes_shared_ref (void)
GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1);
GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes));
- g_assert (bytes == other);
+ g_assert_true (bytes == other);
g_assert_cmpint (bytes->ref_count, ==, 2);
g_bytes_unref (bytes);
@@ -156,7 +156,7 @@ static void
on_destroy_increment (gpointer data)
{
gint *count = data;
- g_assert (count != NULL);
+ g_assert_nonnull (count);
(*count)++;
}
@@ -170,9 +170,9 @@ test_new_with_free_func (void)
data = "test";
bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count);
- g_assert (bytes != NULL);
+ g_assert_nonnull (bytes);
g_assert_cmpint (count, ==, 0);
- g_assert (g_bytes_get_data (bytes, &size) == data);
+ g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
@@ -193,7 +193,7 @@ test_hash (void)
hash1 = g_bytes_hash (bytes1);
hash2 = g_bytes_hash (bytes2);
- g_assert (hash1 == hash2);
+ g_assert_cmpuint (hash1, ==, hash2);
g_bytes_unref (bytes1);
g_bytes_unref (bytes2);
@@ -208,18 +208,18 @@ test_equal (void)
bytes = g_bytes_new ("blah", 4);
bytes2 = g_bytes_new ("blah", 4);
- g_assert (g_bytes_equal (bytes, bytes2));
- g_assert (g_bytes_equal (bytes2, bytes));
+ g_assert_true (g_bytes_equal (bytes, bytes2));
+ g_assert_true (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("bla", 3);
- g_assert (!g_bytes_equal (bytes, bytes2));
- g_assert (!g_bytes_equal (bytes2, bytes));
+ g_assert_false (g_bytes_equal (bytes, bytes2));
+ g_assert_false (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("true", 4);
- g_assert (!g_bytes_equal (bytes, bytes2));
- g_assert (!g_bytes_equal (bytes2, bytes));
+ g_assert_false (g_bytes_equal (bytes, bytes2));
+ g_assert_false (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
g_bytes_unref (bytes);
@@ -272,7 +272,7 @@ test_to_data_transferred (void)
bytes = g_bytes_new (NYAN, N_NYAN);
memory = g_bytes_get_data (bytes, NULL);
data = g_bytes_unref_to_data (bytes, &size);
- g_assert (data == memory);
+ g_assert_true (data == memory);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
}
@@ -290,10 +290,10 @@ test_to_data_two_refs (void)
bytes = g_bytes_ref (bytes);
memory = g_bytes_get_data (bytes, NULL);
data = g_bytes_unref_to_data (bytes, &size);
- g_assert (data != memory);
+ g_assert_true (data != memory);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
- g_assert (g_bytes_get_data (bytes, &size) == memory);
+ g_assert_true (g_bytes_get_data (bytes, &size) == memory);
g_assert_cmpuint (size, ==, N_NYAN);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
g_bytes_unref (bytes);
@@ -308,14 +308,38 @@ test_to_data_non_malloc (void)
/* Memory copied: non malloc memory */
bytes = g_bytes_new_static (NYAN, N_NYAN);
- g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
+ g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
data = g_bytes_unref_to_data (bytes, &size);
- g_assert (data != (gpointer)NYAN);
+ g_assert_true (data != (gpointer)NYAN);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
}
static void
+test_to_data_different_free_func (void)
+{
+ gpointer data;
+ gsize size;
+ GBytes *bytes;
+ gchar *sentinel = g_strdup ("hello");
+
+ /* Memory copied: free func and user_data don’t point to the bytes data */
+ bytes = g_bytes_new_with_free_func (NYAN, N_NYAN, g_free, sentinel);
+ g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
+
+ data = g_bytes_unref_to_data (bytes, &size);
+ g_assert_true (data != (gpointer)NYAN);
+ g_assert_cmpmem (data, size, NYAN, N_NYAN);
+ g_free (data);
+
+ /* @sentinel should not be leaked; testing that requires this test to be run
+ * under valgrind. We can’t use a custom free func to check it isn’t leaked,
+ * as the point of this test is to hit a condition in `try_steal_and_unref()`
+ * which is short-circuited if the free func isn’t g_free().
+ * See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2152 */
+}
+
+static void
test_to_array_transferred (void)
{
gconstpointer memory;
@@ -326,8 +350,8 @@ test_to_array_transferred (void)
bytes = g_bytes_new (NYAN, N_NYAN);
memory = g_bytes_get_data (bytes, NULL);
array = g_bytes_unref_to_array (bytes);
- g_assert (array != NULL);
- g_assert (array->data == memory);
+ g_assert_nonnull (array);
+ g_assert_true (array->data == memory);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
}
@@ -377,11 +401,11 @@ test_to_array_two_refs (void)
bytes = g_bytes_ref (bytes);
memory = g_bytes_get_data (bytes, NULL);
array = g_bytes_unref_to_array (bytes);
- g_assert (array != NULL);
- g_assert (array->data != memory);
+ g_assert_nonnull (array);
+ g_assert_true (array->data != memory);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
- g_assert (g_bytes_get_data (bytes, &size) == memory);
+ g_assert_true (g_bytes_get_data (bytes, &size) == memory);
g_assert_cmpuint (size, ==, N_NYAN);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
g_bytes_unref (bytes);
@@ -395,10 +419,10 @@ test_to_array_non_malloc (void)
/* Memory copied: non malloc memory */
bytes = g_bytes_new_static (NYAN, N_NYAN);
- g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
+ g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
array = g_bytes_unref_to_array (bytes);
- g_assert (array != NULL);
- g_assert (array->data != (gpointer)NYAN);
+ g_assert_nonnull (array);
+ g_assert_true (array->data != (gpointer)NYAN);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
}
@@ -414,8 +438,47 @@ test_null (void)
data = g_bytes_unref_to_data (bytes, &size);
- g_assert (data == NULL);
- g_assert (size == 0);
+ g_assert_null (data);
+ g_assert_cmpuint (size, ==, 0);
+}
+
+static void
+test_get_region (void)
+{
+ GBytes *bytes;
+
+ bytes = g_bytes_new_static (NYAN, N_NYAN);
+
+ /* simple valid gets at the start */
+ g_assert_true (g_bytes_get_region (bytes, 1, 0, 1) == NYAN);
+ g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN) == NYAN);
+
+ /* an invalid get because the range is too wide */
+ g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN + 1) == NULL);
+
+ /* an valid get, but of a zero-byte range at the end */
+ g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 0) == NYAN + N_NYAN);
+
+ /* not a valid get because it overlap ones byte */
+ g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 1) == NULL);
+
+ /* let's try some multiplication overflow now */
+ g_assert_true (g_bytes_get_region (bytes, 32, 0, G_MAXSIZE / 32 + 1) == NULL);
+ g_assert_true (g_bytes_get_region (bytes, G_MAXSIZE / 32 + 1, 0, 32) == NULL);
+
+ /* and some addition overflow */
+ g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, -G_MAXSIZE) == NULL);
+ g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSSIZE, ((gsize) G_MAXSSIZE) + 1) == NULL);
+ g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, 1) == NULL);
+
+ g_bytes_unref (bytes);
+}
+
+static void
+test_unref_null (void)
+{
+ g_test_summary ("Test that calling g_bytes_unref() on NULL is a no-op");
+ g_bytes_unref (NULL);
}
int
@@ -423,8 +486,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugzilla.gnome.org/");
-
g_test_add_func ("/bytes/new", test_new);
g_test_add_func ("/bytes/new-take", test_new_take);
g_test_add_func ("/bytes/new-static", test_new_static);
@@ -438,11 +499,14 @@ main (int argc, char *argv[])
g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred);
g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
+ g_test_add_func ("/bytes/to-data/different-free-func", test_to_data_different_free_func);
g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
g_test_add_func ("/bytes/null", test_null);
+ g_test_add_func ("/bytes/get-region", test_get_region);
+ g_test_add_func ("/bytes/unref-null", test_unref_null);
return g_test_run ();
}
diff --git a/glib/tests/charset.c b/glib/tests/charset.c
index 363eedfd1..53f12ec72 100644
--- a/glib/tests/charset.c
+++ b/glib/tests/charset.c
@@ -76,8 +76,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugs.gnome.org/");
-
g_test_add_func ("/charset/language_names_with_category", test_language_names_with_category);
g_test_add_func ("/charset/language_names_with_category_async", test_language_names_with_category_async);
diff --git a/glib/tests/cond.c b/glib/tests/cond.c
index ed338cce3..bcd8fbd8c 100644
--- a/glib/tests/cond.c
+++ b/glib/tests/cond.c
@@ -324,8 +324,7 @@ test_wait_until_errno (void)
act.sa_handler = signal_handler;
g_test_summary ("Check proper handling of errno in g_cond_wait_until with a contended mutex");
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/");
- g_test_bug ("merge_requests/957");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/957");
g_mutex_init (&lock);
g_cond_init (&cond);
diff --git a/glib/tests/date.c b/glib/tests/date.c
index 542293c4b..5c60ffcba 100644
--- a/glib/tests/date.c
+++ b/glib/tests/date.c
@@ -242,7 +242,7 @@ test_month_substring (void)
{
GDate date;
- g_test_bug ("793550");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=793550");
if (setlocale (LC_ALL, "pl_PL") == NULL)
{
@@ -282,7 +282,7 @@ test_month_names (void)
#endif
#endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */
- g_test_bug ("749206");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=749206");
/* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we
* need the translations to be installed. We can’t mess around with
@@ -789,7 +789,6 @@ main (int argc, char** argv)
#endif
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/date/basic", test_basic);
g_test_add_func ("/date/empty", test_empty_constructor);
diff --git a/glib/tests/error.c b/glib/tests/error.c
index 48f480222..51a0c35dc 100644
--- a/glib/tests/error.c
+++ b/glib/tests/error.c
@@ -70,6 +70,27 @@ test_prefix (void)
}
static void
+test_prefix_literal (void)
+{
+ GError *error = NULL;
+
+ g_prefix_error_literal (NULL, "foo: ");
+
+ g_prefix_error_literal (&error, "foo: ");
+ g_assert_null (error);
+
+ error = NULL;
+ g_prefix_error_literal (&error, "foo: ");
+ g_assert_null (error);
+
+ error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
+ g_assert_nonnull (error);
+ g_prefix_error_literal (&error, "foo: ");
+ g_assert_cmpstr (error->message, ==, "foo: bla");
+ g_error_free (error);
+}
+
+static void
test_literal (void)
{
GError *error;
@@ -374,6 +395,7 @@ main (int argc, char *argv[])
g_test_add_func ("/error/overwrite", test_overwrite);
g_test_add_func ("/error/prefix", test_prefix);
+ g_test_add_func ("/error/prefix-literal", test_prefix_literal);
g_test_add_func ("/error/literal", test_literal);
g_test_add_func ("/error/copy", test_copy);
g_test_add_func ("/error/matches", test_matches);
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index 76ba9086d..a3c1c33d0 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -1439,7 +1439,7 @@ test_fopen_modes (void)
"ab+"
};
- g_test_bug ("119");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/119");
if (g_file_test (path, G_FILE_TEST_EXISTS))
g_error ("failed, %s exists, cannot test g_fopen()", path);
@@ -1826,8 +1826,6 @@ main (int argc,
g_setenv ("LC_ALL", "C", TRUE);
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/merge_requests/");
-
#ifdef G_OS_WIN32
g_test_add_func ("/fileutils/stdio-win32-pathstrip", test_win32_pathstrip);
g_test_add_func ("/fileutils/stdio-win32-zero-terminate-symlink", test_win32_zero_terminate_symlink);
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index bc4eba93a..12f332b44 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -2318,6 +2318,116 @@ test_format_iso8601 (void)
g_time_zone_unref (tz);
}
+typedef struct
+{
+ gboolean utf8_messages;
+ gboolean utf8_time;
+} MixedUtf8TestData;
+
+static const MixedUtf8TestData utf8_time_non_utf8_messages = {
+ .utf8_messages = FALSE,
+ .utf8_time = TRUE
+};
+
+static const MixedUtf8TestData non_utf8_time_utf8_messages = {
+ .utf8_messages = TRUE,
+ .utf8_time = FALSE
+};
+
+static const MixedUtf8TestData utf8_time_utf8_messages = {
+ .utf8_messages = TRUE,
+ .utf8_time = TRUE
+};
+
+static const MixedUtf8TestData non_utf8_time_non_utf8_messages = {
+ .utf8_messages = FALSE,
+ .utf8_time = FALSE
+};
+
+static gboolean
+check_and_set_locale (int category,
+ const gchar *name)
+{
+ setlocale (category, name);
+ if (strstr (setlocale (category, NULL), name) == NULL)
+ {
+ g_print ("Unavaible '%s' locale\n", name);
+ g_test_skip ("required locale not available, skipping tests");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+test_format_time_mixed_utf8 (gconstpointer data)
+{
+ const MixedUtf8TestData *test_data;
+ gchar *old_time_locale;
+ gchar *old_messages_locale;
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2055");
+
+ test_data = (MixedUtf8TestData *) data;
+ old_time_locale = g_strdup (setlocale (LC_TIME, NULL));
+ old_messages_locale = g_strdup (setlocale (LC_MESSAGES, NULL));
+ if (test_data->utf8_time)
+ {
+ if (!check_and_set_locale (LC_TIME, "C.UTF-8"))
+ {
+ g_free (old_time_locale);
+ setlocale (LC_MESSAGES, old_messages_locale);
+ g_free (old_messages_locale);
+ return;
+ }
+ }
+ else
+ {
+ if (!check_and_set_locale (LC_TIME, "de_DE.iso88591"))
+ {
+ g_free (old_time_locale);
+ setlocale (LC_MESSAGES, old_messages_locale);
+ g_free (old_messages_locale);
+ return;
+ }
+ }
+ if (test_data->utf8_messages)
+ {
+ if (!check_and_set_locale (LC_MESSAGES, "C.UTF-8"))
+ {
+ g_free (old_messages_locale);
+ setlocale (LC_TIME, old_time_locale);
+ g_free (old_time_locale);
+ return;
+ }
+ }
+ else
+ {
+ if (!check_and_set_locale (LC_MESSAGES, "de_DE.iso88591"))
+ {
+ g_free (old_messages_locale);
+ setlocale (LC_TIME, old_time_locale);
+ g_free (old_time_locale);
+ return;
+ }
+ }
+
+ if (!test_data->utf8_time)
+ {
+ /* March to have März in german */
+ TEST_PRINTF_DATE (2020, 3, 1, "%b", "Mär");
+ TEST_PRINTF_DATE (2020, 3, 1, "%B", "März");
+ }
+ else
+ {
+ TEST_PRINTF_DATE (2020, 3, 1, "%b", "mar");
+ TEST_PRINTF_DATE (2020, 3, 1, "%B", "march");
+ }
+
+ setlocale (LC_TIME, old_time_locale);
+ setlocale (LC_MESSAGES, old_messages_locale);
+ g_free (old_time_locale);
+ g_free (old_messages_locale);
+}
+
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-y2k"
static void
@@ -2980,6 +3090,18 @@ main (gint argc,
g_test_add_func ("/GDateTime/non_utf8_printf", test_non_utf8_printf);
g_test_add_func ("/GDateTime/format_unrepresentable", test_format_unrepresentable);
g_test_add_func ("/GDateTime/format_iso8601", test_format_iso8601);
+ g_test_add_data_func ("/GDateTime/format_mixed/utf8_time_non_utf8_messages",
+ &utf8_time_non_utf8_messages,
+ test_format_time_mixed_utf8);
+ g_test_add_data_func ("/GDateTime/format_mixed/utf8_time_utf8_messages",
+ &utf8_time_utf8_messages,
+ test_format_time_mixed_utf8);
+ g_test_add_data_func ("/GDateTime/format_mixed/non_utf8_time_non_utf8_messages",
+ &non_utf8_time_non_utf8_messages,
+ test_format_time_mixed_utf8);
+ g_test_add_data_func ("/GDateTime/format_mixed/non_utf8_time_utf8_messages",
+ &non_utf8_time_utf8_messages,
+ test_format_time_mixed_utf8);
g_test_add_func ("/GDateTime/strftime", test_strftime);
g_test_add_func ("/GDateTime/strftime/error_handling", test_GDateTime_strftime_error_handling);
g_test_add_func ("/GDateTime/modifiers", test_modifiers);
diff --git a/glib/tests/gutils-user-database.c b/glib/tests/gutils-user-database.c
index aef599a7b..89a0e0b0f 100644
--- a/glib/tests/gutils-user-database.c
+++ b/glib/tests/gutils-user-database.c
@@ -35,7 +35,6 @@ int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/issues");
g_test_add_func ("/gutils/get_user_database_entry", test_get_user_database_entry);
diff --git a/glib/tests/guuid.c b/glib/tests/guuid.c
index 41e2c81e9..bfe27955b 100644
--- a/glib/tests/guuid.c
+++ b/glib/tests/guuid.c
@@ -61,7 +61,6 @@ int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
/* GUuid Tests */
g_test_add_func ("/uuid/string", test_guuid_string);
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 35434cae9..0110f2664 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -997,7 +997,7 @@ check_offsets (GVariantTypeInfo *info,
position++;
/* and store the offset, just like it would be in the
- * serialised data.
+ * serialized data.
*/
last_offset = position;
last_offset_index++;
@@ -1093,7 +1093,7 @@ test_gvarianttypeinfo (void)
#define MAX_TUPLE_CHILDREN 128
/* this function generates a random type such that all characteristics
- * that are "interesting" to the serialiser are tested.
+ * that are "interesting" to the serializer are tested.
*
* this basically means:
* - test different alignments
@@ -2311,19 +2311,19 @@ test_serialiser_children (void)
g_test_summary ("Test that getting a child variant before and after "
"serialisation of the parent works");
- /* Construct a variable sized array containing a child which serialises to a
+ /* Construct a variable sized array containing a child which serializes to a
* zero-length bytestring. */
child = g_variant_new_maybe (G_VARIANT_TYPE_VARIANT, NULL);
variant = g_variant_new_array (mv_type, &child, 1);
- /* Get the child before serialising. */
+ /* Get the child before serializing. */
child1 = g_variant_get_child_value (variant, 0);
data1 = g_variant_get_data_as_bytes (child1);
- /* Serialise the parent variant. */
+ /* Serialize the parent variant. */
g_variant_get_data (variant);
- /* Get the child again after serialising — this uses a different code path. */
+ /* Get the child again after serializing — this uses a different code path. */
child2 = g_variant_get_child_value (variant, 0);
data2 = g_variant_get_data_as_bytes (child2);
@@ -2348,7 +2348,7 @@ test_fuzz (gdouble *fuzziness)
/* make an instance */
tree = tree_instance_new (NULL, 3);
- /* serialise it */
+ /* serialize it */
serialise_tree (tree, &serialised);
g_assert_true (g_variant_serialised_is_normal (serialised));
@@ -2371,17 +2371,17 @@ test_fuzz (gdouble *fuzziness)
}
}
- /* at least one byte in the serialised data has changed.
+ /* at least one byte in the serialized data has changed.
*
* this means that at least one of the following is true:
*
- * - the serialised data now represents a different value:
+ * - the serialized data now represents a different value:
* check_tree() will return FALSE
*
- * - the serialised data is in non-normal form:
+ * - the serialized data is in non-normal form:
* g_variant_serialiser_is_normal() will return FALSE
*
- * we always do both checks to increase exposure of the serialiser
+ * we always do both checks to increase exposure of the serializer
* to corrupt data.
*/
a = g_variant_serialised_is_normal (serialised);
@@ -3743,9 +3743,9 @@ test_gv_byteswap (void)
# define swapped16(x) x, 0
#endif
/* all kinds of of crazy randomised testing already performed on the
- * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
- * of crazy randomised testing performed against the serialiser
- * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
+ * byteswapper in the /gvariant/serializer/byteswap test and all kinds
+ * of crazy randomised testing performed against the serializer
+ * normalisation functions in the /gvariant/serializer/fuzz/ tests.
*
* just test a few simple cases here to make sure they each work
*/
@@ -4755,7 +4755,7 @@ test_gbytes (void)
g_bytes_unref (bytes2);
tuple = g_variant_new_parsed ("['foo', 'bar']");
- bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
+ bytes = g_variant_get_data_as_bytes (tuple); /* force serialization */
a = g_variant_get_child_value (tuple, 1);
bytes2 = g_variant_get_data_as_bytes (a);
g_assert_false (g_bytes_equal (bytes, bytes2));
@@ -4898,7 +4898,7 @@ test_normal_checking_tuples (void)
}
/* Check that deeply nested variants are not considered in normal form when
- * deserialised from untrusted data.*/
+ * deserialized from untrusted data.*/
static void
test_recursion_limits_variant_in_variant (void)
{
@@ -4914,7 +4914,7 @@ test_recursion_limits_variant_in_variant (void)
for (i = 0; i < G_VARIANT_MAX_RECURSION_DEPTH - 1; i++)
wrapper_variant = g_variant_new_variant (g_steal_pointer (&wrapper_variant));
- /* Serialise and deserialise it as untrusted data, to force normalisation. */
+ /* Serialize and deserialize it as untrusted data, to force normalisation. */
bytes = g_variant_get_data_as_bytes (wrapper_variant);
deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT,
bytes, FALSE);
@@ -4935,7 +4935,7 @@ test_recursion_limits_variant_in_variant (void)
g_variant_unref (deserialised_variant);
- /* Deserialise it again, but trusted this time. This should succeed. */
+ /* Deserialize it again, but trusted this time. This should succeed. */
deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT,
bytes, TRUE);
g_assert_nonnull (deserialised_variant);
@@ -4947,7 +4947,7 @@ test_recursion_limits_variant_in_variant (void)
}
/* Check that deeply nested arrays are not considered in normal form when
- * deserialised from untrusted data after being wrapped in a variant. This is
+ * deserialized from untrusted data after being wrapped in a variant. This is
* worth testing, because neither the deeply nested array, nor the variant,
* have a static #GVariantType which is too deep — only when nested together do
* they become too deep. */
@@ -4967,7 +4967,7 @@ test_recursion_limits_array_in_variant (void)
for (i = 0; i < G_VARIANT_MAX_RECURSION_DEPTH - 1; i++)
child_variant = g_variant_new_array (NULL, &child_variant, 1);
- /* Serialise and deserialise it as untrusted data, to force normalisation. */
+ /* Serialize and deserialize it as untrusted data, to force normalisation. */
bytes = g_variant_get_data_as_bytes (child_variant);
deserialised_variant = g_variant_new_from_bytes (g_variant_get_type (child_variant),
bytes, FALSE);
@@ -4988,7 +4988,7 @@ test_recursion_limits_array_in_variant (void)
g_variant_unref (deserialised_variant);
- /* Deserialise it again, but trusted this time. This should succeed. */
+ /* Deserialize it again, but trusted this time. This should succeed. */
deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT,
bytes, TRUE);
g_assert_nonnull (deserialised_variant);
@@ -5122,7 +5122,6 @@ main (int argc, char **argv)
guint i;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("");
g_test_add_func ("/gvariant/type", test_gvarianttype);
g_test_add_func ("/gvariant/type/string-scan/recursion/tuple",
diff --git a/glib/tests/hash.c b/glib/tests/hash.c
index f4ff55ce1..fe72606f8 100644
--- a/glib/tests/hash.c
+++ b/glib/tests/hash.c
@@ -759,7 +759,7 @@ test_lookup_null_key (void)
gpointer key;
gpointer value;
- g_test_bug ("642944");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642944");
h = g_hash_table_new (null_safe_str_hash, null_safe_str_equal);
g_hash_table_insert (h, "abc", "ABC");
@@ -1012,7 +1012,7 @@ test_destroy_modify (void)
FakeFreeData *ffd;
guint i;
- g_test_bug ("650459");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=650459");
fake_free_data = g_ptr_array_new ();
@@ -1518,7 +1518,7 @@ test_iter_replace (void)
gpointer k, v;
gchar *s;
- g_test_bug ("662544");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=662544");
h = g_hash_table_new_full (g_str_hash, g_str_equal, my_key_free, my_value_free);
@@ -1555,7 +1555,7 @@ test_set_insert_corruption (void)
gchar b[] = "foo";
gpointer key, value;
- g_test_bug ("692815");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=692815");
g_hash_table_insert (hash_table, a, a);
g_assert (g_hash_table_contains (hash_table, "foo"));
@@ -1664,8 +1664,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/hash/misc", test_hash_misc);
g_test_add_data_func ("/hash/one", GINT_TO_POINTER (TRUE), second_hash_test);
g_test_add_data_func ("/hash/honeyman", GINT_TO_POINTER (FALSE), second_hash_test);
diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c
index 975ef8167..1f5be8b38 100644
--- a/glib/tests/keyfile.c
+++ b/glib/tests/keyfile.c
@@ -897,7 +897,7 @@ test_group_remove (void)
"key1=bla\n"
"key2=bla\n";
- g_test_bug ("165887");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=165887");
keyfile = load_data (data, 0);
@@ -952,7 +952,7 @@ test_key_remove (void)
"key1=bla\n"
"key2=bla\n";
- g_test_bug ("165980");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=165980");
keyfile = load_data (data, 0);
@@ -986,7 +986,7 @@ test_groups (void)
"[2]\n"
"key2=123\n";
- g_test_bug ("316309");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=316309");
keyfile = load_data (data, 0);
@@ -1267,7 +1267,7 @@ test_duplicate_groups (void)
"[Desktop Entry]\n"
"key2=123\n";
- g_test_bug ("157877");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=157877");
keyfile = load_data (data, 0);
check_string_value (keyfile, "Desktop Entry", "key1", "123");
@@ -1288,7 +1288,7 @@ test_duplicate_groups2 (void)
"[A]\n"
"foo=bang\n";
- g_test_bug ("385910");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=385910");
keyfile = load_data (data, 0);
check_string_value (keyfile, "A", "foo", "bang");
@@ -1324,7 +1324,7 @@ test_reload_idempotency (void)
gchar *data1, *data2;
gsize len1, len2;
- g_test_bug ("420686");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=420686");
/* check that we only insert a single new line between groups */
keyfile = g_key_file_new ();
@@ -1371,7 +1371,7 @@ test_int64 (void)
gint64 d;
gchar *value;
- g_test_bug ("614864");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=614864");
file = g_key_file_new ();
@@ -1552,7 +1552,7 @@ test_page_boundary (void)
#define LAST_KEY 99
#define VALUE 92
- g_test_bug ("640695");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640695");
file = g_key_file_new ();
@@ -1823,8 +1823,6 @@ main (int argc, char *argv[])
g_setenv ("XDG_DATA_HOME", g_test_get_dir (G_TEST_DIST), TRUE);
#endif
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/keyfile/line-ends", test_line_ends);
g_test_add_func ("/keyfile/whitespace", test_whitespace);
g_test_add_func ("/keyfile/comments", test_comments);
diff --git a/glib/tests/logging.c b/glib/tests/logging.c
index 096fe4467..e246cdf5b 100644
--- a/glib/tests/logging.c
+++ b/glib/tests/logging.c
@@ -340,7 +340,7 @@ test_handler (const gchar *log_domain,
static void
bug653052 (void)
{
- g_test_bug ("653052");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=653052");
g_test_log_set_fatal_handler (good_failure_handler, fail_str);
g_log_set_default_handler (test_handler, log_str);
@@ -637,7 +637,6 @@ main (int argc, char *argv[])
g_unsetenv ("G_MESSAGES_DEBUG");
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/logging/default-handler", test_default_handler);
g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error);
diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c
index d43b2cf08..77e21f548 100644
--- a/glib/tests/mainloop.c
+++ b/glib/tests/mainloop.c
@@ -21,6 +21,7 @@
*/
#include <glib.h>
+#include <glib/gstdio.h>
#include "glib-private.h"
#include <stdio.h>
#include <string.h>
@@ -686,7 +687,7 @@ test_blocked_child_sources (void)
GMainLoop *loop;
GSource *source;
- g_test_bug ("701283");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=701283");
ctx = g_main_context_new ();
loop = g_main_loop_new (ctx, FALSE);
@@ -885,7 +886,7 @@ test_mainloop_overflow (void)
TestOverflowData data;
guint i;
- g_test_bug ("687098");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=687098");
memset (&data, 0, sizeof (data));
@@ -2066,13 +2067,42 @@ test_maincontext_source_finalization_from_dispatch (gconstpointer user_data)
g_main_context_unref (c);
}
+static void
+test_steal_fd (void)
+{
+ GError *error = NULL;
+ gchar *tmpfile = NULL;
+ int fd = -42;
+ int borrowed;
+ int stolen;
+
+ g_assert_cmpint (g_steal_fd (&fd), ==, -42);
+ g_assert_cmpint (fd, ==, -1);
+ g_assert_cmpint (g_steal_fd (&fd), ==, -1);
+ g_assert_cmpint (fd, ==, -1);
+
+ fd = g_file_open_tmp (NULL, &tmpfile, &error);
+ g_assert_cmpint (fd, >=, 0);
+ g_assert_no_error (error);
+ borrowed = fd;
+ stolen = g_steal_fd (&fd);
+ g_assert_cmpint (fd, ==, -1);
+ g_assert_cmpint (borrowed, ==, stolen);
+
+ g_close (g_steal_fd (&stolen), &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (stolen, ==, -1);
+
+ g_assert_no_errno (remove (tmpfile));
+ g_free (tmpfile);
+}
+
int
main (int argc, char *argv[])
{
gint i;
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/maincontext/basic", test_maincontext_basic);
g_test_add_func ("/maincontext/source_finalization", test_maincontext_source_finalization);
@@ -2111,6 +2141,7 @@ main (int argc, char *argv[])
g_test_add_func ("/mainloop/unix-fd-priority", test_unix_fd_priority);
#endif
g_test_add_func ("/mainloop/nfds", test_nfds);
+ g_test_add_func ("/mainloop/steal-fd", test_steal_fd);
return g_test_run ();
}
diff --git a/glib/tests/mem-overflow.c b/glib/tests/mem-overflow.c
index 61225b763..1654ab7fc 100644
--- a/glib/tests/mem-overflow.c
+++ b/glib/tests/mem-overflow.c
@@ -191,7 +191,7 @@ empty_alloc_subprocess (void)
static void
empty_alloc (void)
{
- g_test_bug ("615379");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=615379");
g_assert_cmpint (sizeof (Empty), ==, 0);
@@ -210,8 +210,6 @@ main (int argc,
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/mem/overflow", mem_overflow);
g_test_add_func ("/mem/overflow/subprocess/malloc_n_a_a", mem_overflow_malloc_n_a_a);
g_test_add_func ("/mem/overflow/subprocess/malloc_n_a_b", mem_overflow_malloc_n_a_b);
diff --git a/glib/tests/once.c b/glib/tests/once.c
index 8fc8d5014..ea521c05b 100644
--- a/glib/tests/once.c
+++ b/glib/tests/once.c
@@ -192,7 +192,7 @@ test_once_init_multi_threaded (void)
static void
test_once_init_string (void)
{
- static const gchar *val;
+ static gchar *val;
g_test_summary ("Test g_once_init_{enter,leave}() usage with a string");
diff --git a/glib/tests/option-argv0.c b/glib/tests/option-argv0.c
index ce3609743..37ac44a9f 100644
--- a/glib/tests/option-argv0.c
+++ b/glib/tests/option-argv0.c
@@ -35,7 +35,7 @@ test_platform_argv0 (void)
gboolean arg;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
const gchar * const expected_prgnames[] =
{
"option-argv0",
diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c
index 13d3ffc76..d4ed3a94f 100644
--- a/glib/tests/option-context.c
+++ b/glib/tests/option-context.c
@@ -28,37 +28,19 @@
#include <locale.h>
#include <math.h>
-#ifdef _MSC_VER
-# ifndef NAN
-/*
- * From the Visual Studio 2013+ math.h, we have the following:
- * #ifndef _HUGE_ENUF
- * #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
- * #endif
- *
- * #define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
- * ...
- * #define NAN ((float)(INFINITY * 0.0F))
- * ...
- * so, HUVE_VAL * HUGE_VAL would be a good approximation of INFINITY without
- * defining anything extra
- */
-# define NAN HUGE_VAL * HUGE_VAL * 0.0f
-# endif
-#endif
static GOptionEntry main_entries[] = {
{ "main-switch", 0, 0,
G_OPTION_ARG_NONE, NULL,
"A switch that is in the main group", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static GOptionEntry group_entries[] = {
{ "test-switch", 0, 0,
G_OPTION_ARG_NONE, NULL,
"A switch that is in the test group", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
static GOptionContext *
@@ -134,7 +116,7 @@ test_group_captions (void)
guint i;
gsize j;
- g_test_bug ("504142");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=504142");
for (i = 0; i < 4; ++i)
{
@@ -334,7 +316,7 @@ error_test1 (void)
GOptionGroup *main_group;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
error_test1_int = 0x12345678;
@@ -402,7 +384,7 @@ error_test2 (void)
GOptionGroup *main_group;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
error_test2_string = "foo";
@@ -468,7 +450,7 @@ error_test3 (void)
GOptionGroup *main_group;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
error_test3_boolean = FALSE;
@@ -508,7 +490,7 @@ arg_test1 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -543,7 +525,7 @@ arg_test2 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -577,7 +559,7 @@ arg_test3 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -611,7 +593,7 @@ arg_test4 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -645,7 +627,7 @@ arg_test5 (void)
const char *locale = "de_DE.UTF-8";
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -692,7 +674,7 @@ arg_test6 (void)
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
{ "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -733,7 +715,7 @@ callback_test1 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -774,7 +756,7 @@ callback_test2 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -818,7 +800,7 @@ callback_test_optional_1 (void)
GOptionEntry entries [] =
{ { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -854,7 +836,7 @@ callback_test_optional_2 (void)
GOptionEntry entries [] =
{ { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -890,7 +872,7 @@ callback_test_optional_3 (void)
GOptionEntry entries [] =
{ { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -927,7 +909,7 @@ callback_test_optional_4 (void)
GOptionEntry entries [] =
{ { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -965,7 +947,7 @@ callback_test_optional_5 (void)
{ { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
{ "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1003,7 +985,7 @@ callback_test_optional_6 (void)
{ { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
{ "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1041,7 +1023,7 @@ callback_test_optional_7 (void)
{ { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
{ "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1079,7 +1061,7 @@ callback_test_optional_8 (void)
{ { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
{ "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
callback_parse_optional, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1123,7 +1105,7 @@ callback_remaining_test1 (void)
int argc;
GOptionEntry entries [] =
{ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
callback_remaining_args = g_ptr_array_new ();
context = g_option_context_new (NULL);
@@ -1170,7 +1152,7 @@ callback_returns_false (void)
{ { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
{ "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
{ "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1253,7 +1235,7 @@ ignore_test1 (void)
gchar *arg;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (context, TRUE);
@@ -1289,7 +1271,7 @@ ignore_test2 (void)
gchar *arg;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (context, TRUE);
@@ -1324,7 +1306,7 @@ ignore_test3 (void)
gchar *arg;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (context, TRUE);
@@ -1362,7 +1344,7 @@ array_test1 (void)
int argc;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1394,10 +1376,10 @@ add_test1 (void)
GOptionEntry entries1 [] =
{ { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
GOptionEntry entries2 [] =
{ { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries1, NULL);
@@ -1445,7 +1427,7 @@ rest_test1 (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1483,7 +1465,7 @@ rest_test2 (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1522,7 +1504,7 @@ rest_test2a (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1559,7 +1541,7 @@ rest_test2b (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1597,7 +1579,7 @@ rest_test2c (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1634,7 +1616,7 @@ rest_test2d (void)
int argc;
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1674,7 +1656,7 @@ rest_test3 (void)
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1715,7 +1697,7 @@ rest_test4 (void)
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1755,7 +1737,7 @@ rest_test5 (void)
GOptionEntry entries [] = {
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1791,9 +1773,9 @@ unknown_short_test (void)
gchar **argv;
gchar **argv_copy;
int argc;
- GOptionEntry entries [] = { { NULL } };
+ GOptionEntry entries [] = { G_OPTION_ENTRY_NULL };
- g_test_bug ("166609");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=166609");
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1823,7 +1805,7 @@ lonely_dash_test (void)
gchar **argv_copy;
int argc;
- g_test_bug ("168008");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=168008");
context = g_option_context_new (NULL);
@@ -1856,11 +1838,11 @@ triple_dash_test (void)
gint arg1, arg2;
GOptionEntry entries [] =
{ { "foo", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionEntry group_entries [] =
{ { "test", 0, 0, G_OPTION_ARG_INT, &arg2, NULL, NULL},
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new (NULL);
@@ -1897,9 +1879,9 @@ missing_arg_test (void)
gchar *arg = NULL;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
- g_test_bug ("305576");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=305576");
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -1963,9 +1945,9 @@ dash_arg_test (void)
GOptionEntry entries [] =
{ { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL },
{ "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
- g_test_bug ("577638");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=577638");
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -2008,7 +1990,7 @@ test_basic (void)
gchar *arg = NULL;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -2069,7 +2051,7 @@ test_translate (void)
gchar *arg = NULL;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
TranslateData data = { 0, };
gchar *str;
@@ -2103,12 +2085,12 @@ test_help (void)
{ "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
{ "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionEntry group_entries[] = {
{ "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
{ "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
context = g_option_context_new ("blabla");
@@ -2152,7 +2134,7 @@ test_help_no_options (void)
gchar **sarr = NULL;
GOptionEntry entries[] = {
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
gchar *str;
@@ -2182,15 +2164,15 @@ test_help_no_help_options (void)
{ "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
{ "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionEntry group_entries[] = {
{ "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
{ "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
- g_test_bug ("697652");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=697652");
context = g_option_context_new ("blabla");
g_option_context_add_main_entries (context, entries, NULL);
@@ -2278,7 +2260,7 @@ test_error_hook (void)
gchar *arg = NULL;
GOptionEntry entries [] =
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
GOptionGroup *group;
gchar **argv;
gchar **argv_copy;
@@ -2323,13 +2305,13 @@ test_group_parse (void)
GOptionEntry entries[] = {
{ "test", 't', 0, G_OPTION_ARG_STRING, &arg1, NULL, NULL },
{ "faz", 'f', 0, G_OPTION_ARG_STRING, &arg2, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionEntry group_entries[] = {
{ "test", 0, 0, G_OPTION_ARG_STRING, &arg3, NULL, NULL },
{ "frob", 'f', 0, G_OPTION_ARG_STRING, &arg4, NULL, NULL },
{ "faz", 'z', 0, G_OPTION_ARG_STRING, &arg5, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
gchar **argv, **orig_argv;
gint argc;
@@ -2393,7 +2375,7 @@ test_strict_posix (void)
GOptionEntry entries[] = {
{ "foo", 'f', 0, G_OPTION_ARG_NONE, &foo, NULL, NULL },
{ "bar", 'b', 0, G_OPTION_ARG_NONE, &bar, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
gint n_parsed;
@@ -2438,7 +2420,7 @@ flag_reverse_string (void)
gchar *arg = NULL;
GOptionEntry entries [] =
{ { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
gchar **argv;
gint argc;
gboolean retval;
@@ -2471,7 +2453,7 @@ flag_optional_int (void)
gint arg = 0;
GOptionEntry entries [] =
{ { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
gchar **argv;
gint argc;
gboolean retval;
@@ -2512,13 +2494,13 @@ short_remaining (void)
{ "number", 'n', 0, G_OPTION_ARG_INT, &number, NULL, NULL },
{ "text", 't', 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionContext* context;
gchar **argv, **argv_copy;
gint argc;
- g_test_bug ("729563");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=729563");
argv = split_string ("program -ri -n 4 -t hello file1 file2", &argc);
argv_copy = copy_stringv (argv, argc);
@@ -2553,14 +2535,14 @@ double_free (void)
GOptionEntry entries[] =
{
{ "known", 0, 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GOptionContext* context;
gchar **argv;
gint argc;
GError *error = NULL;
- g_test_bug ("646926");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=646926");
argv = split_string ("program --known=foo --known=bar --unknown=baz", &argc);
@@ -2591,7 +2573,7 @@ double_zero (void)
double test_val = NAN;
GOptionEntry entries [] =
{ { "test", 0, 0, G_OPTION_ARG_DOUBLE, &test_val, NULL, NULL },
- { NULL } };
+ G_OPTION_ENTRY_NULL };
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
@@ -2622,8 +2604,6 @@ main (int argc,
g_setenv ("LC_ALL", "C", TRUE);
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/option/help/options", test_help);
g_test_add_func ("/option/help/no-options", test_help_no_options);
g_test_add_func ("/option/help/no-help-options", test_help_no_help_options);
diff --git a/glib/tests/pattern.c b/glib/tests/pattern.c
index 70553a882..ecc27db26 100644
--- a/glib/tests/pattern.c
+++ b/glib/tests/pattern.c
@@ -51,12 +51,12 @@ struct _CompileTest
guint min;
};
-static CompileTest compile_tests[] =
-{
+static CompileTest compile_tests[] = {
{ "*A?B*", G_MATCH_ALL, "*A?B*", 3 },
{ "ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8 },
{ "ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8 },
{ "ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11 },
+ { "**ABC***?🤌DEF**", G_MATCH_ALL, "*ABC*?🤌DEF*", 11 },
{ "*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4 },
{ "ABCD*", G_MATCH_HEAD, "ABCD", 4 },
{ "*ABCD", G_MATCH_TAIL, "ABCD", 4 },
@@ -84,6 +84,24 @@ test_compilation (gconstpointer d)
g_pattern_spec_free (spec);
}
+static void
+test_copy (gconstpointer d)
+{
+ const CompileTest *test = d;
+ GPatternSpec *p1, *p2;
+
+ p1 = g_pattern_spec_new (test->src);
+ p2 = g_pattern_spec_copy (p1);
+
+ g_assert_cmpint (p2->match_type, ==, test->match_type);
+ g_assert_cmpstr (p2->pattern, ==, test->pattern);
+ g_assert_cmpint (p2->pattern_length, ==, strlen (p1->pattern));
+ g_assert_cmpint (p2->min_length, ==, test->min);
+
+ g_pattern_spec_free (p1);
+ g_pattern_spec_free (p2);
+}
+
typedef struct _MatchTest MatchTest;
struct _MatchTest
@@ -158,10 +176,16 @@ test_match (gconstpointer d)
g_assert_cmpint (g_pattern_match_simple (test->pattern, test->string), ==, test->match);
p = g_pattern_spec_new (test->pattern);
+ g_assert_cmpint (g_pattern_spec_match_string (p, test->string), ==, test->match);
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_cmpint (g_pattern_match_string (p, test->string), ==, test->match);
+ G_GNUC_END_IGNORE_DEPRECATIONS
r = g_utf8_strreverse (test->string, -1);
+ g_assert_cmpint (g_pattern_spec_match (p, strlen (test->string), test->string, r), ==, test->match);
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_cmpint (g_pattern_match (p, strlen (test->string), test->string, r), ==, test->match);
+ G_GNUC_END_IGNORE_DEPRECATIONS
g_free (r);
g_pattern_spec_free (p);
@@ -222,6 +246,13 @@ main (int argc, char** argv)
g_free (path);
}
+ for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
+ {
+ path = g_strdup_printf ("/pattern/copy/%" G_GSIZE_FORMAT, i);
+ g_test_add_data_func (path, &compile_tests[i], test_copy);
+ g_free (path);
+ }
+
for (i = 0; i < G_N_ELEMENTS (match_tests); i++)
{
path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i);
diff --git a/glib/tests/rand.c b/glib/tests/rand.c
index 94fb4e822..37f4ddd41 100644
--- a/glib/tests/rand.c
+++ b/glib/tests/rand.c
@@ -160,7 +160,7 @@ test_double_range (void)
{
gdouble d;
- g_test_bug ("502560");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=502560");
d = g_random_double_range (-G_MAXDOUBLE, G_MAXDOUBLE);
@@ -173,7 +173,6 @@ main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/rand/test-rand", test_rand);
g_test_add_func ("/rand/double-range", test_double_range);
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index c57bd8cdc..88d12edf6 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -25,11 +25,7 @@
#include <locale.h>
#include "glib.h"
-#ifdef USE_SYSTEM_PCRE
#include <pcre.h>
-#else
-#include "glib/pcre/pcre.h"
-#endif
/* U+20AC EURO SIGN (symbol, currency) */
#define EURO "\xe2\x82\xac"
@@ -2124,7 +2120,7 @@ test_multiline (void)
GMatchInfo *info;
gint count;
- g_test_bug ("640489");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640489");
regex = g_regex_new ("^a$", G_REGEX_MULTILINE|G_REGEX_DOTALL, 0, NULL);
@@ -2194,8 +2190,6 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/regex/properties", test_properties);
g_test_add_func ("/regex/class", test_class);
g_test_add_func ("/regex/lookahead", test_lookahead);
@@ -2559,13 +2553,16 @@ main (int argc, char *argv[])
TEST_SUB_PATTERN("(a)?(b)", "b", 0, 0, "b", 0, 1);
TEST_SUB_PATTERN("(a)?(b)", "b", 0, 1, "", -1, -1);
TEST_SUB_PATTERN("(a)?(b)", "b", 0, 2, "b", 0, 1);
+ TEST_SUB_PATTERN("(a)?b", "b", 0, 0, "b", 0, 1);
+ TEST_SUB_PATTERN("(a)?b", "b", 0, 1, "", -1, -1);
+ TEST_SUB_PATTERN("(a)?b", "b", 0, 2, NULL, UNTOUCHED, UNTOUCHED);
/* TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name,
* expected_sub, expected_start, expected_end) */
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "ab", 0, "A", "b", 1, 2);
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "aab", 1, "A", "b", 2, 3);
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "A", "b", 4, 5);
- TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "B", NULL, UNTOUCHED, UNTOUCHED);
+ TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "B", "", -1, -1);
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "C", NULL, UNTOUCHED, UNTOUCHED);
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "A", EGRAVE, 1, 3);
TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "B", "x", 3, 4);
@@ -2677,7 +2674,7 @@ main (int argc, char *argv[])
TEST_EXPAND("a", "a", "\\0130", FALSE, "X");
TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a");
TEST_EXPAND("a(?P<G>.)c", "xabcy", "X\\g<G>X", FALSE, "XbX");
-#ifndef USE_SYSTEM_PCRE
+#if !(PCRE_MAJOR > 8 || (PCRE_MAJOR == 8 && PCRE_MINOR >= 34))
/* PCRE >= 8.34 no longer allows this usage. */
TEST_EXPAND("(.)(?P<1>.)", "ab", "\\1", FALSE, "a");
TEST_EXPAND("(.)(?P<1>.)", "ab", "\\g<1>", FALSE, "a");
diff --git a/glib/tests/spawn-path-search-helper.c b/glib/tests/spawn-path-search-helper.c
index 378c203c7..37be43b7f 100644
--- a/glib/tests/spawn-path-search-helper.c
+++ b/glib/tests/spawn-path-search-helper.c
@@ -79,7 +79,7 @@ main (int argc,
{ "slow-path", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &slow_path,
"Use a child-setup function to avoid the posix_spawn fast path", NULL },
- { NULL }
+ G_OPTION_ENTRY_NULL
};
GError *error = NULL;
int ret = 1;
diff --git a/glib/tests/spawn-singlethread.c b/glib/tests/spawn-singlethread.c
index 51a1da514..6b17027fd 100644
--- a/glib/tests/spawn-singlethread.c
+++ b/glib/tests/spawn-singlethread.c
@@ -408,17 +408,17 @@ test_spawn_nonexistent (void)
GError *error = NULL;
GPtrArray *argv = NULL;
gchar *stdout_str = NULL;
- gint exit_status = -1;
+ gint wait_status = -1;
argv = g_ptr_array_new ();
g_ptr_array_add (argv, "this does not exist");
g_ptr_array_add (argv, NULL);
g_spawn_sync (NULL, (char**) argv->pdata, NULL, 0, NULL, NULL, &stdout_str,
- NULL, &exit_status, &error);
+ NULL, &wait_status, &error);
g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT);
g_assert_null (stdout_str);
- g_assert_cmpint (exit_status, ==, -1);
+ g_assert_cmpint (wait_status, ==, -1);
g_ptr_array_free (argv, TRUE);
@@ -433,7 +433,7 @@ test_spawn_nonexistent (void)
static void
test_spawn_fd_assignment_clash (void)
{
-#ifdef G_OS_UNIX
+#if defined(G_OS_UNIX) && defined(F_DUPFD_CLOEXEC)
int tmp_fd;
guint i;
const guint n_fds = 10;
@@ -487,7 +487,7 @@ test_spawn_fd_assignment_clash (void)
for (i = 0; i < n_fds; i++)
g_close (source_fds[i], NULL);
#else /* !G_OS_UNIX */
- g_test_skip ("FD redirection only supported on Unix");
+ g_test_skip ("FD redirection only supported on Unix with F_DUPFD_CLOEXEC");
#endif /* !G_OS_UNIX */
}
diff --git a/glib/tests/string.c b/glib/tests/string.c
index 24098d1be..6e22cd287 100644
--- a/glib/tests/string.c
+++ b/glib/tests/string.c
@@ -498,64 +498,30 @@ test_string_to_bytes (void)
static void
test_string_replace (void)
{
- static const struct
- {
- const char *string;
- const char *original;
- const char *replacement;
- guint limit;
- const char *expected;
- guint expected_n;
- }
- tests[] =
- {
- { "foo bar foo baz foo bar foobarbaz", "bar", "baz", 0,
- "foo baz foo baz foo baz foobazbaz", 3 },
- { "foo baz foo baz foo baz foobazbaz", "baz", "bar", 3,
- "foo bar foo bar foo bar foobazbaz", 3 },
- { "foo bar foo bar foo bar foobazbaz", "foobar", "bar", 1,
- "foo bar foo bar foo bar foobazbaz", 0 },
- { "aaaaaaaa", "a", "abcdefghijkl", 0,
- "abcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijkl",
- 8 },
- { "/usr/$LIB/libMangoHud.so", "$LIB", "lib32", 0,
- "/usr/lib32/libMangoHud.so", 1 },
- { "food for foals", "o", "", 0,
- "fd fr fals", 4 },
- { "aaa", "a", "aaa", 0,
- "aaaaaaaaa", 3 },
- { "aaa", "a", "", 0,
- "", 3 },
- { "aaa", "aa", "bb", 0,
- "bba", 1 },
- { "foo", "", "bar", 0,
- "barfbarobarobar", 4 },
- { "", "", "x", 0,
- "x", 1 },
- { "", "", "", 0,
- "", 1 },
- };
- gsize i;
-
- for (i = 0; i < G_N_ELEMENTS (tests); i++)
- {
- GString *s;
- guint n;
-
- s = g_string_new (tests[i].string);
- g_test_message ("%" G_GSIZE_FORMAT ": Replacing \"%s\" with \"%s\" (limit %u) in \"%s\"",
- i, tests[i].original, tests[i].replacement,
- tests[i].limit, tests[i].string);
- n = g_string_replace (s, tests[i].original, tests[i].replacement,
- tests[i].limit);
- g_test_message ("-> %u replacements, \"%s\"",
- n, s->str);
- g_assert_cmpstr (tests[i].expected, ==, s->str);
- g_assert_cmpuint (strlen (tests[i].expected), ==, s->len);
- g_assert_cmpuint (strlen (tests[i].expected) + 1, <=, s->allocated_len);
- g_assert_cmpuint (tests[i].expected_n, ==, n);
- g_string_free (s, TRUE);
- }
+ GString *s;
+ gint n;
+
+ s = g_string_new ("foo bar foo baz foo bar foobarbaz");
+
+ n = g_string_replace (s, "bar", "baz", 0);
+ g_assert_cmpstr ("foo baz foo baz foo baz foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 3);
+
+ n = g_string_replace (s, "baz", "bar", 3);
+ g_assert_cmpstr ("foo bar foo bar foo bar foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 3);
+
+ n = g_string_replace (s, "foobar", "bar", 1);
+ g_assert_cmpstr ("foo bar foo bar foo bar foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 0);
+
+ s = g_string_assign (s, "aaaaaaaa");
+ n = g_string_replace (s, "a", "abcdefghijkl", 0);
+ g_assert_cmpstr ("abcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijkl",
+ ==, s->str);
+ g_assert_cmpint (n, ==, 8);
+
+ g_string_free (s, TRUE);
}
int
diff --git a/glib/tests/strvbuilder.c b/glib/tests/strvbuilder.c
index 5f3b9329f..904af0e71 100644
--- a/glib/tests/strvbuilder.c
+++ b/glib/tests/strvbuilder.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2020 Canonical Ltd.
+ * Copyright © 2021 Alexandros Theodotou
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
@@ -56,6 +57,40 @@ test_strvbuilder_add (void)
}
static void
+test_strvbuilder_addv (void)
+{
+ GStrvBuilder *builder;
+ GStrv result;
+ const gchar *expected[] = { "one", "two", "three", NULL };
+
+ builder = g_strv_builder_new ();
+ g_strv_builder_addv (builder, expected);
+ result = g_strv_builder_end (builder);
+ g_assert_nonnull (result);
+ g_assert_cmpstrv ((const gchar *const *) result, expected);
+
+ g_strfreev (result);
+ g_strv_builder_unref (builder);
+}
+
+static void
+test_strvbuilder_add_many (void)
+{
+ GStrvBuilder *builder;
+ GStrv result;
+ const gchar *expected[] = { "one", "two", "three", NULL };
+
+ builder = g_strv_builder_new ();
+ g_strv_builder_add_many (builder, "one", "two", "three", NULL);
+ result = g_strv_builder_end (builder);
+ g_assert_nonnull (result);
+ g_assert_cmpstrv ((const gchar *const *) result, expected);
+
+ g_strfreev (result);
+ g_strv_builder_unref (builder);
+}
+
+static void
test_strvbuilder_ref (void)
{
GStrvBuilder *builder;
@@ -74,6 +109,8 @@ main (int argc,
g_test_add_func ("/strvbuilder/empty", test_strvbuilder_empty);
g_test_add_func ("/strvbuilder/add", test_strvbuilder_add);
+ g_test_add_func ("/strvbuilder/addv", test_strvbuilder_addv);
+ g_test_add_func ("/strvbuilder/add_many", test_strvbuilder_add_many);
g_test_add_func ("/strvbuilder/ref", test_strvbuilder_ref);
return g_test_run ();
diff --git a/glib/tests/test-printf.c b/glib/tests/test-printf.c
index dd1107432..59a461ddb 100644
--- a/glib/tests/test-printf.c
+++ b/glib/tests/test-printf.c
@@ -728,7 +728,7 @@ test_64bit (void)
/* However, gcc doesn't know about this, so we need to disable printf
* format warnings...
*/
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if G_GNUC_CHECK_VERSION(4, 6)
_Pragma ("GCC diagnostic push")
_Pragma ("GCC diagnostic ignored \"-Wformat\"")
_Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"")
@@ -766,7 +766,7 @@ _Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"")
g_assert_cmpint (res, ==, 5);
g_assert_cmpstr (buf, ==, "1E240");
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if G_GNUC_CHECK_VERSION(4, 6)
_Pragma ("GCC diagnostic pop")
#endif
@@ -819,7 +819,7 @@ test_64bit2_win32 (void)
/* However, gcc doesn't know about this, so we need to disable printf
* format warnings...
*/
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if G_GNUC_CHECK_VERSION(4, 6)
_Pragma ("GCC diagnostic push")
_Pragma ("GCC diagnostic ignored \"-Wformat\"")
_Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"")
@@ -849,7 +849,7 @@ _Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"")
res = g_printf ("%" "ll" "X\n", (gint64)123456);
g_assert_cmpint (res, ==, 6);
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if G_GNUC_CHECK_VERSION(4, 6)
_Pragma ("GCC diagnostic pop")
#endif
}
diff --git a/glib/tests/testing.c b/glib/tests/testing.c
index 7faa7b5ec..81b8f5405 100644
--- a/glib/tests/testing.c
+++ b/glib/tests/testing.c
@@ -878,7 +878,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@@ -900,7 +900,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@@ -918,7 +918,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 77);
g_clear_error (&error);
@@ -940,7 +940,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one pass and some incomplete -> overall status 0");
@@ -959,7 +959,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one pass and mix of skipped and incomplete -> overall status 0");
@@ -980,7 +980,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_test_message ("one fail and some skipped -> overall status fail");
@@ -1001,7 +1001,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@@ -1021,7 +1021,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@@ -1043,7 +1043,7 @@ test_combining (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_clear_error (&error);
@@ -1075,7 +1075,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nok 1 /pass\n"));
g_free (output);
@@ -1094,7 +1094,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nok 1 /skip # SKIP not enough tea\n"));
g_free (output);
@@ -1113,7 +1113,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_assert_nonnull (strstr (output, "\nnot ok 1 /incomplete # TODO mind reading not implemented yet\n"));
g_free (output);
@@ -1132,7 +1132,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
g_assert_nonnull (strstr (output, "\nnot ok 1 /fail\n"));
g_free (output);
@@ -1166,7 +1166,7 @@ test_tap (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_ptr_array_unref (argv);
@@ -1197,7 +1197,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1229,7 +1229,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1261,7 +1261,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP\n"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a # SKIP\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1292,7 +1292,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 5 /b/b\n"));
g_assert_nonnull (strstr (output, "\n1..5\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1324,7 +1324,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 6 /b/b/a\n"));
g_assert_nonnull (strstr (output, "\n1..6\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1350,7 +1350,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 2 /b/b/a\n"));
g_assert_nonnull (strstr (output, "\n1..2\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1374,7 +1374,7 @@ test_tap (void)
NULL, NULL, &output, NULL, &status,
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_nonnull (error);
g_assert_nonnull (strstr (output, "do not mix [-r | --run-prefix] with '-p'\n"));
g_clear_error (&error);
@@ -1416,7 +1416,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1453,7 +1453,7 @@ test_tap (void)
g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request"));
g_assert_nonnull (strstr (output, "\nok 10 /d/a\n"));
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
g_free (output);
@@ -1477,7 +1477,7 @@ test_tap (void)
NULL, NULL, &output, NULL, &status,
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_nonnull (error);
g_assert_nonnull (strstr (output, "do not mix [-x | --skip-prefix] with '-s'\n"));
g_clear_error (&error);
@@ -1511,7 +1511,7 @@ test_tap_summary (void)
&error);
g_assert_no_error (error);
- g_spawn_check_exit_status (status, &error);
+ g_spawn_check_wait_status (status, &error);
g_assert_no_error (error);
/* Note: The test path in the output is not `/tap/summary` because it’s the
* test path from testing-helper, not from this function. */
diff --git a/glib/tests/thread-pool.c b/glib/tests/thread-pool.c
index 703da5d7a..50a72a632 100644
--- a/glib/tests/thread-pool.c
+++ b/glib/tests/thread-pool.c
@@ -88,6 +88,12 @@ dummy_pool_func (gpointer data, gpointer user_data)
}
static void
+dummy_pool_func_full (gpointer data, gpointer user_data)
+{
+ g_assert_true (data == user_data);
+}
+
+static void
test_create_first_pool (gconstpointer shared_first)
{
GThreadPool *pool;
@@ -142,6 +148,55 @@ test_create_first_pool (gconstpointer shared_first)
g_thread_pool_free (pool, TRUE, TRUE);
}
+static void
+free_func (gpointer user_data)
+{
+ gboolean *free_func_called = user_data;
+ *free_func_called = TRUE;
+}
+
+static void
+test_thread_pool_full (gconstpointer shared_first)
+{
+ GThreadPool *pool;
+ gboolean free_func_called = FALSE;
+ GError *err = NULL;
+ gboolean success;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/121");
+
+ g_thread_pool_set_max_unused_threads (0);
+
+ if (GPOINTER_TO_INT (shared_first))
+ pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, -1, FALSE, &err);
+ else
+ pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, 2, TRUE, &err);
+ g_assert_no_error (err);
+ g_assert_nonnull (pool);
+
+ success = g_thread_pool_push (pool, &free_func_called, &err);
+ g_assert_no_error (err);
+ g_assert_true (success);
+
+ g_thread_pool_free (pool, TRUE, TRUE);
+ g_assert_true (free_func_called);
+
+ free_func_called = FALSE;
+ if (GPOINTER_TO_INT (shared_first))
+ pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, 2, TRUE, &err);
+ else
+ pool = g_thread_pool_new_full (dummy_pool_func_full, &free_func_called, free_func, -1, FALSE, &err);
+ g_assert_no_error (err);
+ g_assert_nonnull (pool);
+
+ success = g_thread_pool_push (pool, &free_func_called, &err);
+ g_assert_no_error (err);
+ g_assert_true (success);
+
+ g_thread_pool_free (pool, TRUE, TRUE);
+ g_assert_true (free_func_called);
+}
+
int
main (int argc, char *argv[])
{
@@ -150,6 +205,7 @@ main (int argc, char *argv[])
g_test_add_data_func ("/thread_pool/shared", GINT_TO_POINTER (TRUE), test_simple);
g_test_add_data_func ("/thread_pool/exclusive", GINT_TO_POINTER (FALSE), test_simple);
g_test_add_data_func ("/thread_pool/create_shared_after_exclusive", GINT_TO_POINTER (FALSE), test_create_first_pool);
+ g_test_add_data_func ("/thread_pool/create_full", GINT_TO_POINTER (FALSE), test_thread_pool_full);
g_test_add_data_func ("/thread_pool/create_exclusive_after_shared", GINT_TO_POINTER (TRUE), test_create_first_pool);
return g_test_run ();
diff --git a/glib/tests/tree.c b/glib/tests/tree.c
index 8811d962d..5174479b9 100644
--- a/glib/tests/tree.c
+++ b/glib/tests/tree.c
@@ -68,17 +68,21 @@ my_search (gconstpointer a,
static gpointer destroyed_key = NULL;
static gpointer destroyed_value = NULL;
+static guint destroyed_key_count = 0;
+static guint destroyed_value_count = 0;
static void
my_key_destroy (gpointer key)
{
destroyed_key = key;
+ destroyed_key_count++;
}
static void
my_value_destroy (gpointer value)
{
destroyed_value = value;
+ destroyed_value_count++;
}
static gint
@@ -282,6 +286,32 @@ test_tree_remove (void)
}
static void
+test_tree_remove_all (void)
+{
+ GTree *tree;
+ gsize i;
+
+ tree = g_tree_new_full ((GCompareDataFunc)my_compare, NULL,
+ my_key_destroy,
+ my_value_destroy);
+
+ for (i = 0; chars[i]; i++)
+ g_tree_insert (tree, &chars[i], &chars[i]);
+
+ destroyed_key_count = 0;
+ destroyed_value_count = 0;
+
+ g_tree_remove_all (tree);
+
+ g_assert_cmpuint (destroyed_key_count, ==, strlen (chars));
+ g_assert_cmpuint (destroyed_value_count, ==, strlen (chars));
+ g_assert_cmpint (g_tree_height (tree), ==, 0);
+ g_assert_cmpint (g_tree_nnodes (tree), ==, 0);
+
+ g_tree_unref (tree);
+}
+
+static void
test_tree_destroy (void)
{
GTree *tree;
@@ -462,6 +492,7 @@ main (int argc, char *argv[])
g_test_add_func ("/tree/destroy", test_tree_destroy);
g_test_add_func ("/tree/traverse", test_tree_traverse);
g_test_add_func ("/tree/insert", test_tree_insert);
+ g_test_add_func ("/tree/remove-all", test_tree_remove_all);
return g_test_run ();
}
diff --git a/glib/tests/uri.c b/glib/tests/uri.c
index 1f3209f97..7a251af64 100644
--- a/glib/tests/uri.c
+++ b/glib/tests/uri.c
@@ -714,7 +714,7 @@ static const UriAbsoluteTest absolute_tests[] = {
/* ".." past top */
{ "http://example.com/..", G_URI_FLAGS_NONE, TRUE, 0,
- { "http", NULL, "example.com", -1, "/..", NULL, NULL }
+ { "http", NULL, "example.com", -1, "/", NULL, NULL }
},
/* scheme parsing */
diff --git a/glib/tests/utf8-validate.c b/glib/tests/utf8-validate.c
index 51543f4b2..5fc37a3a3 100644
--- a/glib/tests/utf8-validate.c
+++ b/glib/tests/utf8-validate.c
@@ -268,7 +268,7 @@ Test test[] = {
{ "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
{ "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
- { NULL, }
+ { NULL, 0, 0, 0 }
};
static void
diff --git a/glib/tests/utils.c b/glib/tests/utils.c
index 2c5d16c3a..f47e3595c 100644
--- a/glib/tests/utils.c
+++ b/glib/tests/utils.c
@@ -161,7 +161,7 @@ test_appname (void)
static void
test_tmpdir (void)
{
- g_test_bug ("627969");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=627969");
g_assert_cmpstr (g_get_tmp_dir (), !=, "");
}
@@ -246,6 +246,11 @@ test_find_program (void)
gchar *res;
#ifdef G_OS_UNIX
+ gchar *relative_path;
+ gchar *absolute_path;
+ gchar *cwd;
+ gsize i;
+
res = g_find_program_in_path ("sh");
g_assert (res != NULL);
g_free (res);
@@ -253,6 +258,27 @@ test_find_program (void)
res = g_find_program_in_path ("/bin/sh");
g_assert (res != NULL);
g_free (res);
+
+ cwd = g_get_current_dir ();
+ absolute_path = g_find_program_in_path ("sh");
+ relative_path = g_strdup (absolute_path);
+ for (i = 0; cwd[i] != '\0'; i++)
+ {
+ if (cwd[i] == '/' && cwd[i + 1] != '\0')
+ {
+ gchar *relative_path_2 = g_strconcat ("../", relative_path, NULL);
+ g_free (relative_path);
+ relative_path = relative_path_2;
+ }
+ }
+ res = g_find_program_in_path (relative_path);
+ g_assert_nonnull (res);
+ g_assert_true (g_path_is_absolute (res));
+ g_free (cwd);
+ g_free (absolute_path);
+ g_free (relative_path);
+ g_free (res);
+
#else
/* There's not a lot we can search for that would reliably work both
* on real Windows and mingw.
@@ -829,7 +855,6 @@ main (int argc,
g_set_prgname (argv[0]);
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/utils/language-names", test_language_names);
g_test_add_func ("/utils/locale-variants", test_locale_variants);
diff --git a/glib/tests/win32.c b/glib/tests/win32.c
index 97e5887cf..121997311 100644
--- a/glib/tests/win32.c
+++ b/glib/tests/win32.c
@@ -33,34 +33,40 @@ static char *argv0 = NULL;
static void
test_subst_pid_and_event (void)
{
- const gchar not_enough[] = "too long when %e and %p are substituted";
- gchar debugger_3[3];
- gchar debugger_not_enough[G_N_ELEMENTS (not_enough)];
- gchar debugger_enough[G_N_ELEMENTS (not_enough) + 1];
- gchar debugger_big[65535] = {0};
+ const wchar_t not_enough[] = L"too long when %e and %p are substituted";
+ wchar_t debugger_3[3];
+ wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)];
+ wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1];
+ char *debugger_enough_utf8;
+ wchar_t debugger_big[65535] = {0};
+ char *debugger_big_utf8;
gchar *output;
guintptr be = (guintptr) 0xFFFFFFFF;
DWORD bp = G_MAXSIZE;
/* %f is not valid */
- g_assert_false (_g_win32_subst_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
- "%f", 0, 0));
+ g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
+ L"%f", 0, 0));
- g_assert_false (_g_win32_subst_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
- "string longer than 10", 0, 0));
+ g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
+ L"string longer than 10", 0, 0));
/* 200 is longer than %e, so the string doesn't fit by 1 byte */
- g_assert_false (_g_win32_subst_pid_and_event (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
- "too long when %e and %p are substituted", 10, 200));
+ g_assert_false (_g_win32_subst_pid_and_event_w (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
+ not_enough, 10, 200));
/* This should fit */
- g_assert_true (_g_win32_subst_pid_and_event (debugger_enough, G_N_ELEMENTS (debugger_enough),
- "too long when %e and %p are substituted", 10, 200));
- g_assert_cmpstr (debugger_enough, ==, "too long when 200 and 10 are substituted");
-
- g_assert_true (_g_win32_subst_pid_and_event (debugger_big, G_N_ELEMENTS (debugger_big),
- "multipl%e big %e %entries and %pids are %provided here", bp, be));
+ g_assert_true (_g_win32_subst_pid_and_event_w (debugger_enough, G_N_ELEMENTS (debugger_enough),
+ not_enough, 10, 200));
+ debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL);
+ g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted");
+ g_free (debugger_enough_utf8);
+
+ g_assert_true (_g_win32_subst_pid_and_event_w (debugger_big, G_N_ELEMENTS (debugger_big),
+ L"multipl%e big %e %entries and %pids are %provided here", bp, be));
+ debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL);
output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp);
- g_assert_cmpstr (debugger_big, ==, output);
+ g_assert_cmpstr (debugger_big_utf8, ==, output);
+ g_free (debugger_big_utf8);
g_free (output);
}
@@ -95,7 +101,6 @@ test_veh_crash_access_violation (void)
/* Run a test that crashes */
g_test_trap_subprocess ("/win32/subprocess/access_violation", 0, 0);
g_test_trap_assert_failed ();
- g_test_trap_assert_stderr ("Exception code=0xc0000005*");
}
static void
@@ -105,21 +110,11 @@ test_veh_crash_illegal_instruction (void)
/* Run a test that crashes */
g_test_trap_subprocess ("/win32/subprocess/illegal_instruction", 0, 0);
g_test_trap_assert_failed ();
- g_test_trap_assert_stderr ("Exception code=0xc000001d*");
}
static void
test_veh_debug (void)
{
- /* Run a test that crashes and runs a debugger */
- g_test_trap_subprocess ("/win32/subprocess/debuggee", 0, 0);
- g_test_trap_assert_failed ();
- g_test_trap_assert_stderr ("Exception code=0xc0000005*Debugger invoked, attaching to*");
-}
-
-static void
-test_veh_debuggee (void)
-{
/* Set up a debugger to be run on crash */
gchar *command = g_strdup_printf ("%s %s", argv0, "%p %e");
g_setenv ("G_DEBUGGER", command, TRUE);
@@ -129,6 +124,15 @@ test_veh_debuggee (void)
*/
g_setenv ("G_DEBUGGER_OLD_CONSOLE", "1", TRUE);
g_free (command);
+ /* Run a test that crashes and runs a debugger */
+ g_test_trap_subprocess ("/win32/subprocess/debuggee", 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("Debugger invoked, attaching to*");
+}
+
+static void
+test_veh_debuggee (void)
+{
/* Crash */
test_access_violation ();
}
diff --git a/glib/update-pcre/digitab.patch b/glib/update-pcre/digitab.patch
deleted file mode 100644
index a12efc526..000000000
--- a/glib/update-pcre/digitab.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 5238ab10c5f3082a4be38410bd01a47ab176dfde Mon Sep 17 00:00:00 2001
-From: Christian Persch <chpe@gnome.org>
-Date: Sun, 12 Feb 2012 19:29:42 +0100
-Subject: [PATCH] regex: Use g_ascii_is[x]digit
-
----
- glib/pcre/pcre_compile.c | 22 ++++++++++++----------
- 1 files changed, 12 insertions(+), 10 deletions(-)
-
-diff --git a/glib/pcre/pcre_compile.c b/glib/pcre/pcre_compile.c
-index 8070f51..eb985df 100644
---- a/glib/pcre/pcre_compile.c
-+++ b/glib/pcre/pcre_compile.c
-@@ -52,6 +52,7 @@ supporting internal functions that are not used by other modules. */
-
- #include "pcre_internal.h"
-
-+#include "gstrfuncs.h"
-
- /* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which
- is also used by pcretest. PCRE_DEBUG is not defined when building a production
-@@ -513,6 +514,7 @@ into a subtraction and unsigned comparison). */
-
- #define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
-
-+#if 0
- #ifndef EBCDIC
-
- /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
-@@ -626,7 +628,7 @@ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
- #endif
--
-+#endif /* 0 */
-
- /* Definition to allow mutual recursion */
-
-@@ -812,10 +814,10 @@ else
- {
- /* In JavaScript, \u must be followed by four hexadecimal numbers.
- Otherwise it is a lowercase u letter. */
-- if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
-- && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0
-- && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0
-- && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0)
-+ if (MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0
-+ && MAX_255(ptr[2]) && g_ascii_isxdigit(ptr[2]) != 0
-+ && MAX_255(ptr[3]) && g_ascii_isxdigit(ptr[3]) != 0
-+ && MAX_255(ptr[4]) && g_ascii_isxdigit(ptr[4]) != 0)
- {
- c = 0;
- for (i = 0; i < 4; ++i)
-@@ -1012,8 +1014,8 @@ else
- {
- /* 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)
-+ if (MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0
-+ && MAX_255(ptr[2]) && g_ascii_isxdigit(ptr[2]) != 0)
- {
- c = 0;
- for (i = 0; i < 2; ++i)
-@@ -1036,7 +1038,7 @@ else
- const pcre_uchar *pt = ptr + 2;
-
- c = 0;
-- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
-+ while (MAX_255(*pt) && g_ascii_isxdigit(*pt) != 0)
- {
- register int cc = *pt++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
-@@ -1060,7 +1062,7 @@ else
-
- if (c < 0)
- {
-- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
-+ while (MAX_255(*pt) && g_ascii_isxdigit(*pt) != 0) pt++;
- *errorcodeptr = ERR34;
- }
-
-@@ -1078,7 +1080,7 @@ else
- /* Read just a single-byte hex-defined char */
-
- c = 0;
-- while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
-+ while (i++ < 2 && MAX_255(ptr[1]) && g_ascii_isxdigit(ptr[1]) != 0)
- {
- int cc; /* Some compilers don't like */
- cc = *(++ptr); /* ++ in initializers */
---
-1.7.5.1.217.g4e3aa.dirty
-
diff --git a/glib/update-pcre/memory.patch b/glib/update-pcre/memory.patch
deleted file mode 100644
index f3a04c784..000000000
--- a/glib/update-pcre/memory.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From acf401f1353a37b6edff9577ff07d055c625e4ca Mon Sep 17 00:00:00 2001
-From: Christian Persch <chpe@gnome.org>
-Date: Sun, 12 Feb 2012 19:40:48 +0100
-Subject: [PATCH] regex: Use glib memory allocator
-
----
- glib/pcre/pcre_globals.c | 10 ++++++----
- 1 files changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/glib/pcre/pcre_globals.c b/glib/pcre/pcre_globals.c
-index 36e6ddb..93d3af5 100644
---- a/glib/pcre/pcre_globals.c
-+++ b/glib/pcre/pcre_globals.c
-@@ -58,6 +58,8 @@ global variables are not used. */
-
- #include "pcre_internal.h"
-
-+#include "gmem.h"
-+
- #if defined _MSC_VER || defined __SYMBIAN32__
- static void* LocalPcreMalloc(size_t aSize)
- {
-@@ -74,10 +76,10 @@ PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
- PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-
- #elif !defined VPCOMPAT
--PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
--PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free;
--PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
--PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
-+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = g_try_malloc;
-+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = g_free;
-+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = g_try_malloc;
-+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = g_free;
- PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
- #endif
-
---
-1.7.5.1.217.g4e3aa.dirty
-
diff --git a/glib/update-pcre/ucp.patch b/glib/update-pcre/ucp.patch
deleted file mode 100644
index 402020fa8..000000000
--- a/glib/update-pcre/ucp.patch
+++ /dev/null
@@ -1,834 +0,0 @@
-From 23d48c5fc7aa889dc7798f9c64acd43d9cb34683 Mon Sep 17 00:00:00 2001
-From: Christian Persch <chpe@gnome.org>
-Date: Sun, 12 Feb 2012 21:20:33 +0100
-Subject: [PATCH] regex: Use glib for unicode data
-
-Use g_unichar_type() and g_unichar_get_script() instead of pcre tables.
----
- glib/pcre/pcre_compile.c | 26 +++---
- glib/pcre/pcre_dfa_exec.c | 96 ++++++++--------
- glib/pcre/pcre_exec.c | 26 +++---
- glib/pcre/pcre_internal.h | 11 +--
- glib/pcre/pcre_tables.c | 16 +++
- glib/pcre/pcre_xclass.c | 24 ++--
- glib/pcre/ucp.h | 265 +++++++++++++++++++++++----------------------
- 7 files changed, 239 insertions(+), 225 deletions(-)
-
-diff --git a/glib/pcre/pcre_compile.c b/glib/pcre/pcre_compile.c
-index 21bef80..a6c84e1 100644
---- a/glib/pcre/pcre_compile.c
-+++ b/glib/pcre/pcre_compile.c
-@@ -2920,43 +2920,43 @@ Returns: TRUE if auto-possessifying is OK
- static BOOL
- check_char_prop(int c, int ptype, int pdata, BOOL negated)
- {
--const ucd_record *prop = GET_UCD(c);
-+const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(ptype)
- {
- case PT_LAMP:
-- return (prop->chartype == ucp_Lu ||
-- prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt) == negated;
-+ return (chartype == ucp_Lu ||
-+ chartype == ucp_Ll ||
-+ chartype == ucp_Lt) == negated;
-
- case PT_GC:
-- return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
-+ return (pdata == PRIV(ucp_gentype)[chartype]) == negated;
-
- case PT_PC:
-- return (pdata == prop->chartype) == negated;
-+ return (pdata == chartype) == negated;
-
- case PT_SC:
-- return (pdata == prop->script) == negated;
-+ return (pdata == UCD_SCRIPT(c)) == negated;
-
- /* These are specials */
-
- case PT_ALNUM:
-- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
-+ return (PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N) == negated;
-
- case PT_SPACE: /* Perl space */
-- return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ return (PRIV(ucp_gentype)[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 ||
-+ return (PRIV(ucp_gentype)[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 ||
-+ return (PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == negated;
- }
- return FALSE;
-diff --git a/glib/pcre/pcre_dfa_exec.c b/glib/pcre/pcre_dfa_exec.c
-index 9565d46..3f913ce 100644
---- a/glib/pcre/pcre_dfa_exec.c
-+++ b/glib/pcre/pcre_dfa_exec.c
-@@ -1060,7 +1060,7 @@ for (;;)
- if (clen > 0)
- {
- BOOL OK;
-- const ucd_record * prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[1])
- {
- case PT_ANY:
-@@ -1068,43 +1068,43 @@ for (;;)
- break;
-
- case PT_LAMP:
-- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt;
-+ OK = chartype == ucp_Lu || chartype == ucp_Ll ||
-+ chartype == ucp_Lt;
- break;
-
- case PT_GC:
-- OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
-+ OK = PRIV(ucp_gentype)[chartype] == code[2];
- break;
-
- case PT_PC:
-- OK = prop->chartype == code[2];
-+ OK = chartype == code[2];
- break;
-
- case PT_SC:
-- OK = prop->script == code[2];
-+ OK = UCD_SCRIPT(c) == code[2];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
-@@ -1294,7 +1294,7 @@ for (;;)
- if (clen > 0)
- {
- BOOL OK;
-- const ucd_record * prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[2])
- {
- case PT_ANY:
-@@ -1302,43 +1302,43 @@ for (;;)
- break;
-
- case PT_LAMP:
-- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt;
-+ OK = chartype == ucp_Lu || chartype == ucp_Ll ||
-+ chartype == ucp_Lt;
- break;
-
- case PT_GC:
-- OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
-+ OK = PRIV(ucp_gentype)[chartype] == code[3];
- break;
-
- case PT_PC:
-- OK = prop->chartype == code[3];
-+ OK = chartype == code[3];
- break;
-
- case PT_SC:
-- OK = prop->script == code[3];
-+ OK = UCD_SCRIPT(c) == code[3];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
-@@ -1541,7 +1541,7 @@ for (;;)
- if (clen > 0)
- {
- BOOL OK;
-- const ucd_record * prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[2])
- {
- case PT_ANY:
-@@ -1549,43 +1549,43 @@ for (;;)
- break;
-
- case PT_LAMP:
-- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt;
-+ OK = chartype == ucp_Lu || chartype == ucp_Ll ||
-+ chartype == ucp_Lt;
- break;
-
- case PT_GC:
-- OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
-+ OK = PRIV(ucp_gentype)[chartype] == code[3];
- break;
-
- case PT_PC:
-- OK = prop->chartype == code[3];
-+ OK = chartype == code[3];
- break;
-
- case PT_SC:
-- OK = prop->script == code[3];
-+ OK = UCD_SCRIPT(c) == code[3];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
-@@ -1813,7 +1813,7 @@ for (;;)
- if (clen > 0)
- {
- BOOL OK;
-- const ucd_record * prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
- switch(code[1 + IMM2_SIZE + 1])
- {
- case PT_ANY:
-@@ -1821,43 +1821,43 @@ for (;;)
- break;
-
- case PT_LAMP:
-- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt;
-+ OK = chartype == ucp_Lu || chartype == ucp_Ll ||
-+ chartype == ucp_Lt;
- break;
-
- case PT_GC:
-- OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
-+ OK = PRIV(ucp_gentype)[chartype] == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_PC:
-- OK = prop->chartype == code[1 + IMM2_SIZE + 2];
-+ OK = chartype == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_SC:
-- OK = prop->script == code[1 + IMM2_SIZE + 2];
-+ OK = UCD_SCRIPT(c) == code[1 + IMM2_SIZE + 2];
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N;
- break;
-
- case PT_SPACE: /* Perl space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR;
- break;
-
- case PT_WORD:
-- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
-diff --git a/glib/pcre/pcre_exec.c b/glib/pcre/pcre_exec.c
-index 830b8b5..c89a3f9 100644
---- a/glib/pcre/pcre_exec.c
-+++ b/glib/pcre/pcre_exec.c
-@@ -2565,7 +2565,7 @@ for (;;)
- }
- GETCHARINCTEST(c, eptr);
- {
-- const ucd_record *prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
-
- switch(ecode[1])
- {
-@@ -2574,44 +2574,44 @@ for (;;)
- break;
-
- case PT_LAMP:
-- if ((prop->chartype == ucp_Lu ||
-- prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
-+ if ((chartype == ucp_Lu ||
-+ chartype == ucp_Ll ||
-+ chartype == ucp_Lt) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_GC:
-- if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
-+ if ((ecode[2] != PRIV(ucp_gentype)[chartype]) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PC:
-- if ((ecode[2] != prop->chartype) == (op == OP_PROP))
-+ if ((ecode[2] != chartype) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SC:
-- if ((ecode[2] != prop->script) == (op == OP_PROP))
-+ if ((ecode[2] != UCD_SCRIPT(c)) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* These are specials */
-
- case PT_ALNUM:
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SPACE: /* Perl space */
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
-@@ -2619,8 +2619,8 @@ for (;;)
- break;
-
- case PT_WORD:
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-diff --git a/glib/pcre/pcre_internal.h b/glib/pcre/pcre_internal.h
-index 181c312..234af1b 100644
---- a/glib/pcre/pcre_internal.h
-+++ b/glib/pcre/pcre_internal.h
-@@ -2329,15 +2329,12 @@ extern const int PRIV(ucp_typerange)[];
- #ifdef SUPPORT_UCP
- /* UCD access macros */
-
--#define UCD_BLOCK_SIZE 128
--#define GET_UCD(ch) (PRIV(ucd_records) + \
-- PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \
-- UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE])
-+unsigned int _pcre_ucp_othercase(const unsigned int c);
-
--#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
--#define UCD_SCRIPT(ch) GET_UCD(ch)->script
-+#define UCD_CHARTYPE(ch) (pcre_uint8)g_unichar_type((gunichar)(ch))
-+#define UCD_SCRIPT(ch) (pcre_uint8)g_unichar_get_script((gunichar)(ch))
- #define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
--#define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case)
-+#define UCD_OTHERCASE(ch) (_pcre_ucp_othercase(ch))
-
- #endif /* SUPPORT_UCP */
-
-diff --git a/glib/pcre/pcre_tables.c b/glib/pcre/pcre_tables.c
-index 7ac2d89..e401974 100644
---- a/glib/pcre/pcre_tables.c
-+++ b/glib/pcre/pcre_tables.c
-@@ -584,6 +584,22 @@ const ucp_type_table PRIV(utt)[] = {
-
- const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
-
-+unsigned int
-+_pcre_ucp_othercase(const unsigned int c)
-+{
-+ int other_case = NOTACHAR;
-+
-+ if (g_unichar_islower(c))
-+ other_case = g_unichar_toupper(c);
-+ else if (g_unichar_isupper(c))
-+ other_case = g_unichar_tolower(c);
-+
-+ if (other_case == c)
-+ other_case = NOTACHAR;
-+
-+ return other_case;
-+}
-+
- #endif /* SUPPORT_UTF */
-
- /* End of pcre_tables.c */
-diff --git a/glib/pcre/pcre_xclass.c b/glib/pcre/pcre_xclass.c
-index dca7a39..e5a55d7 100644
---- a/glib/pcre/pcre_xclass.c
-+++ b/glib/pcre/pcre_xclass.c
-@@ -127,7 +127,7 @@ while ((t = *data++) != XCL_END)
- #ifdef SUPPORT_UCP
- else /* XCL_PROP & XCL_NOTPROP */
- {
-- const ucd_record *prop = GET_UCD(c);
-+ const pcre_uint8 chartype = UCD_CHARTYPE(c);
-
- switch(*data)
- {
-@@ -136,46 +136,46 @@ while ((t = *data++) != XCL_END)
- break;
-
- case PT_LAMP:
-- if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
-- prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
-+ if ((chartype == ucp_Lu || chartype == ucp_Ll ||
-+ chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_GC:
-- if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
-+ if ((data[1] == PRIV(ucp_gentype)[chartype]) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PC:
-- if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
-+ if ((data[1] == chartype) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_SC:
-- if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
-+ if ((data[1] == UCD_SCRIPT(c)) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_ALNUM:
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_SPACE: /* Perl space */
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PXSPACE: /* POSIX space */
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_WORD:
-- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-- PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
-+ if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
-+ PRIV(ucp_gentype)[chartype] == ucp_N || c == CHAR_UNDERSCORE)
- == (t == XCL_PROP))
- return !negated;
- break;
-diff --git a/glib/pcre/ucp.h b/glib/pcre/ucp.h
-index 59c3bec..53a48c9 100644
---- a/glib/pcre/ucp.h
-+++ b/glib/pcre/ucp.h
-@@ -10,6 +10,7 @@ the UCD access macros. New values that are added for new releases of Unicode
- should always be at the end of each enum, for backwards compatibility. */
-
- /* These are the general character categories. */
-+#include "gunicode.h"
-
- enum {
- ucp_C, /* Other */
-@@ -24,148 +25,148 @@ enum {
- /* These are the particular character types. */
-
- enum {
-- ucp_Cc, /* Control */
-- ucp_Cf, /* Format */
-- ucp_Cn, /* Unassigned */
-- ucp_Co, /* Private use */
-- ucp_Cs, /* Surrogate */
-- ucp_Ll, /* Lower case letter */
-- ucp_Lm, /* Modifier letter */
-- ucp_Lo, /* Other letter */
-- ucp_Lt, /* Title case letter */
-- ucp_Lu, /* Upper case letter */
-- ucp_Mc, /* Spacing mark */
-- ucp_Me, /* Enclosing mark */
-- ucp_Mn, /* Non-spacing mark */
-- ucp_Nd, /* Decimal number */
-- ucp_Nl, /* Letter number */
-- ucp_No, /* Other number */
-- ucp_Pc, /* Connector punctuation */
-- ucp_Pd, /* Dash punctuation */
-- ucp_Pe, /* Close punctuation */
-- ucp_Pf, /* Final punctuation */
-- ucp_Pi, /* Initial punctuation */
-- ucp_Po, /* Other punctuation */
-- ucp_Ps, /* Open punctuation */
-- ucp_Sc, /* Currency symbol */
-- ucp_Sk, /* Modifier symbol */
-- ucp_Sm, /* Mathematical symbol */
-- ucp_So, /* Other symbol */
-- ucp_Zl, /* Line separator */
-- ucp_Zp, /* Paragraph separator */
-- ucp_Zs /* Space separator */
-+ ucp_Cc = G_UNICODE_CONTROL, /* Control */
-+ ucp_Cf = G_UNICODE_FORMAT, /* Format */
-+ ucp_Cn = G_UNICODE_UNASSIGNED, /* Unassigned */
-+ ucp_Co = G_UNICODE_PRIVATE_USE, /* Private use */
-+ ucp_Cs = G_UNICODE_SURROGATE, /* Surrogate */
-+ ucp_Ll = G_UNICODE_LOWERCASE_LETTER, /* Lower case letter */
-+ ucp_Lm = G_UNICODE_MODIFIER_LETTER, /* Modifier letter */
-+ ucp_Lo = G_UNICODE_OTHER_LETTER, /* Other letter */
-+ ucp_Lt = G_UNICODE_TITLECASE_LETTER, /* Title case letter */
-+ ucp_Lu = G_UNICODE_UPPERCASE_LETTER, /* Upper case letter */
-+ ucp_Mc = G_UNICODE_SPACING_MARK, /* Spacing mark */
-+ ucp_Me = G_UNICODE_ENCLOSING_MARK, /* Enclosing mark */
-+ ucp_Mn = G_UNICODE_NON_SPACING_MARK, /* Non-spacing mark */
-+ ucp_Nd = G_UNICODE_DECIMAL_NUMBER, /* Decimal number */
-+ ucp_Nl = G_UNICODE_LETTER_NUMBER, /* Letter number */
-+ ucp_No = G_UNICODE_OTHER_NUMBER, /* Other number */
-+ ucp_Pc = G_UNICODE_CONNECT_PUNCTUATION, /* Connector punctuation */
-+ ucp_Pd = G_UNICODE_DASH_PUNCTUATION, /* Dash punctuation */
-+ ucp_Pe = G_UNICODE_CLOSE_PUNCTUATION, /* Close punctuation */
-+ ucp_Pf = G_UNICODE_FINAL_PUNCTUATION, /* Final punctuation */
-+ ucp_Pi = G_UNICODE_INITIAL_PUNCTUATION, /* Initial punctuation */
-+ ucp_Po = G_UNICODE_OTHER_PUNCTUATION, /* Other punctuation */
-+ ucp_Ps = G_UNICODE_OPEN_PUNCTUATION, /* Open punctuation */
-+ ucp_Sc = G_UNICODE_CURRENCY_SYMBOL, /* Currency symbol */
-+ ucp_Sk = G_UNICODE_MODIFIER_SYMBOL, /* Modifier symbol */
-+ ucp_Sm = G_UNICODE_MATH_SYMBOL, /* Mathematical symbol */
-+ ucp_So = G_UNICODE_OTHER_SYMBOL, /* Other symbol */
-+ ucp_Zl = G_UNICODE_LINE_SEPARATOR, /* Line separator */
-+ ucp_Zp = G_UNICODE_PARAGRAPH_SEPARATOR, /* Paragraph separator */
-+ ucp_Zs = G_UNICODE_SPACE_SEPARATOR /* Space separator */
- };
-
- /* These are the script identifications. */
-
- enum {
-- ucp_Arabic,
-- ucp_Armenian,
-- ucp_Bengali,
-- ucp_Bopomofo,
-- ucp_Braille,
-- ucp_Buginese,
-- ucp_Buhid,
-- ucp_Canadian_Aboriginal,
-- ucp_Cherokee,
-- ucp_Common,
-- ucp_Coptic,
-- ucp_Cypriot,
-- ucp_Cyrillic,
-- ucp_Deseret,
-- ucp_Devanagari,
-- ucp_Ethiopic,
-- ucp_Georgian,
-- ucp_Glagolitic,
-- ucp_Gothic,
-- ucp_Greek,
-- ucp_Gujarati,
-- ucp_Gurmukhi,
-- ucp_Han,
-- ucp_Hangul,
-- ucp_Hanunoo,
-- ucp_Hebrew,
-- ucp_Hiragana,
-- ucp_Inherited,
-- ucp_Kannada,
-- ucp_Katakana,
-- ucp_Kharoshthi,
-- ucp_Khmer,
-- ucp_Lao,
-- ucp_Latin,
-- ucp_Limbu,
-- ucp_Linear_B,
-- ucp_Malayalam,
-- ucp_Mongolian,
-- ucp_Myanmar,
-- ucp_New_Tai_Lue,
-- ucp_Ogham,
-- ucp_Old_Italic,
-- ucp_Old_Persian,
-- ucp_Oriya,
-- ucp_Osmanya,
-- ucp_Runic,
-- ucp_Shavian,
-- ucp_Sinhala,
-- ucp_Syloti_Nagri,
-- ucp_Syriac,
-- ucp_Tagalog,
-- ucp_Tagbanwa,
-- ucp_Tai_Le,
-- ucp_Tamil,
-- ucp_Telugu,
-- ucp_Thaana,
-- ucp_Thai,
-- ucp_Tibetan,
-- ucp_Tifinagh,
-- ucp_Ugaritic,
-- ucp_Yi,
-+ ucp_Arabic = G_UNICODE_SCRIPT_ARABIC,
-+ ucp_Armenian = G_UNICODE_SCRIPT_ARMENIAN,
-+ ucp_Bengali = G_UNICODE_SCRIPT_BENGALI,
-+ ucp_Bopomofo = G_UNICODE_SCRIPT_BOPOMOFO,
-+ ucp_Braille = G_UNICODE_SCRIPT_BRAILLE,
-+ ucp_Buginese = G_UNICODE_SCRIPT_BUGINESE,
-+ ucp_Buhid = G_UNICODE_SCRIPT_BUHID,
-+ ucp_Canadian_Aboriginal = G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
-+ ucp_Cherokee = G_UNICODE_SCRIPT_CHEROKEE,
-+ ucp_Common = G_UNICODE_SCRIPT_COMMON,
-+ ucp_Coptic = G_UNICODE_SCRIPT_COPTIC,
-+ ucp_Cypriot = G_UNICODE_SCRIPT_CYPRIOT,
-+ ucp_Cyrillic = G_UNICODE_SCRIPT_CYRILLIC,
-+ ucp_Deseret = G_UNICODE_SCRIPT_DESERET,
-+ ucp_Devanagari = G_UNICODE_SCRIPT_DEVANAGARI,
-+ ucp_Ethiopic = G_UNICODE_SCRIPT_ETHIOPIC,
-+ ucp_Georgian = G_UNICODE_SCRIPT_GEORGIAN,
-+ ucp_Glagolitic = G_UNICODE_SCRIPT_GLAGOLITIC,
-+ ucp_Gothic = G_UNICODE_SCRIPT_GOTHIC,
-+ ucp_Greek = G_UNICODE_SCRIPT_GREEK,
-+ ucp_Gujarati = G_UNICODE_SCRIPT_GUJARATI,
-+ ucp_Gurmukhi = G_UNICODE_SCRIPT_GURMUKHI,
-+ ucp_Han = G_UNICODE_SCRIPT_HAN,
-+ ucp_Hangul = G_UNICODE_SCRIPT_HANGUL,
-+ ucp_Hanunoo = G_UNICODE_SCRIPT_HANUNOO,
-+ ucp_Hebrew = G_UNICODE_SCRIPT_HEBREW,
-+ ucp_Hiragana = G_UNICODE_SCRIPT_HIRAGANA,
-+ ucp_Inherited = G_UNICODE_SCRIPT_INHERITED,
-+ ucp_Kannada = G_UNICODE_SCRIPT_KANNADA,
-+ ucp_Katakana = G_UNICODE_SCRIPT_KATAKANA,
-+ ucp_Kharoshthi = G_UNICODE_SCRIPT_KHAROSHTHI,
-+ ucp_Khmer = G_UNICODE_SCRIPT_KHMER,
-+ ucp_Lao = G_UNICODE_SCRIPT_LAO,
-+ ucp_Latin = G_UNICODE_SCRIPT_LATIN,
-+ ucp_Limbu = G_UNICODE_SCRIPT_LIMBU,
-+ ucp_Linear_B = G_UNICODE_SCRIPT_LINEAR_B,
-+ ucp_Malayalam = G_UNICODE_SCRIPT_MALAYALAM,
-+ ucp_Mongolian = G_UNICODE_SCRIPT_MONGOLIAN,
-+ ucp_Myanmar = G_UNICODE_SCRIPT_MYANMAR,
-+ ucp_New_Tai_Lue = G_UNICODE_SCRIPT_NEW_TAI_LUE,
-+ ucp_Ogham = G_UNICODE_SCRIPT_OGHAM,
-+ ucp_Old_Italic = G_UNICODE_SCRIPT_OLD_ITALIC,
-+ ucp_Old_Persian = G_UNICODE_SCRIPT_OLD_PERSIAN,
-+ ucp_Oriya = G_UNICODE_SCRIPT_ORIYA,
-+ ucp_Osmanya = G_UNICODE_SCRIPT_OSMANYA,
-+ ucp_Runic = G_UNICODE_SCRIPT_RUNIC,
-+ ucp_Shavian = G_UNICODE_SCRIPT_SHAVIAN,
-+ ucp_Sinhala = G_UNICODE_SCRIPT_SINHALA,
-+ ucp_Syloti_Nagri = G_UNICODE_SCRIPT_SYLOTI_NAGRI,
-+ ucp_Syriac = G_UNICODE_SCRIPT_SYRIAC,
-+ ucp_Tagalog = G_UNICODE_SCRIPT_TAGALOG,
-+ ucp_Tagbanwa = G_UNICODE_SCRIPT_TAGBANWA,
-+ ucp_Tai_Le = G_UNICODE_SCRIPT_TAI_LE,
-+ ucp_Tamil = G_UNICODE_SCRIPT_TAMIL,
-+ ucp_Telugu = G_UNICODE_SCRIPT_TELUGU,
-+ ucp_Thaana = G_UNICODE_SCRIPT_THAANA,
-+ ucp_Thai = G_UNICODE_SCRIPT_THAI,
-+ ucp_Tibetan = G_UNICODE_SCRIPT_TIBETAN,
-+ ucp_Tifinagh = G_UNICODE_SCRIPT_TIFINAGH,
-+ ucp_Ugaritic = G_UNICODE_SCRIPT_UGARITIC,
-+ ucp_Yi = G_UNICODE_SCRIPT_YI,
- /* New for Unicode 5.0: */
-- ucp_Balinese,
-- ucp_Cuneiform,
-- ucp_Nko,
-- ucp_Phags_Pa,
-- ucp_Phoenician,
-+ ucp_Balinese = G_UNICODE_SCRIPT_BALINESE,
-+ ucp_Cuneiform = G_UNICODE_SCRIPT_CUNEIFORM,
-+ ucp_Nko = G_UNICODE_SCRIPT_NKO,
-+ ucp_Phags_Pa = G_UNICODE_SCRIPT_PHAGS_PA,
-+ ucp_Phoenician = G_UNICODE_SCRIPT_PHOENICIAN,
- /* New for Unicode 5.1: */
-- ucp_Carian,
-- ucp_Cham,
-- ucp_Kayah_Li,
-- ucp_Lepcha,
-- ucp_Lycian,
-- ucp_Lydian,
-- ucp_Ol_Chiki,
-- ucp_Rejang,
-- ucp_Saurashtra,
-- ucp_Sundanese,
-- ucp_Vai,
-+ ucp_Carian = G_UNICODE_SCRIPT_CARIAN,
-+ ucp_Cham = G_UNICODE_SCRIPT_CHAM,
-+ ucp_Kayah_Li = G_UNICODE_SCRIPT_KAYAH_LI,
-+ ucp_Lepcha = G_UNICODE_SCRIPT_LEPCHA,
-+ ucp_Lycian = G_UNICODE_SCRIPT_LYCIAN,
-+ ucp_Lydian = G_UNICODE_SCRIPT_LYDIAN,
-+ ucp_Ol_Chiki = G_UNICODE_SCRIPT_OL_CHIKI,
-+ ucp_Rejang = G_UNICODE_SCRIPT_REJANG,
-+ ucp_Saurashtra = G_UNICODE_SCRIPT_SAURASHTRA,
-+ ucp_Sundanese = G_UNICODE_SCRIPT_SUNDANESE,
-+ ucp_Vai = G_UNICODE_SCRIPT_VAI,
- /* New for Unicode 5.2: */
-- ucp_Avestan,
-- ucp_Bamum,
-- ucp_Egyptian_Hieroglyphs,
-- ucp_Imperial_Aramaic,
-- ucp_Inscriptional_Pahlavi,
-- ucp_Inscriptional_Parthian,
-- ucp_Javanese,
-- ucp_Kaithi,
-- ucp_Lisu,
-- ucp_Meetei_Mayek,
-- ucp_Old_South_Arabian,
-- ucp_Old_Turkic,
-- ucp_Samaritan,
-- ucp_Tai_Tham,
-- ucp_Tai_Viet,
-+ ucp_Avestan = G_UNICODE_SCRIPT_AVESTAN,
-+ ucp_Bamum = G_UNICODE_SCRIPT_BAMUM,
-+ ucp_Egyptian_Hieroglyphs = G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS,
-+ ucp_Imperial_Aramaic = G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC,
-+ ucp_Inscriptional_Pahlavi = G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI,
-+ ucp_Inscriptional_Parthian = G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN,
-+ ucp_Javanese = G_UNICODE_SCRIPT_JAVANESE,
-+ ucp_Kaithi = G_UNICODE_SCRIPT_KAITHI,
-+ ucp_Lisu = G_UNICODE_SCRIPT_LISU,
-+ ucp_Meetei_Mayek = G_UNICODE_SCRIPT_MEETEI_MAYEK,
-+ ucp_Old_South_Arabian = G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN,
-+ ucp_Old_Turkic = G_UNICODE_SCRIPT_OLD_TURKIC,
-+ ucp_Samaritan = G_UNICODE_SCRIPT_SAMARITAN,
-+ ucp_Tai_Tham = G_UNICODE_SCRIPT_TAI_THAM,
-+ ucp_Tai_Viet = G_UNICODE_SCRIPT_TAI_VIET,
- /* New for Unicode 6.0.0: */
-- ucp_Batak,
-- ucp_Brahmi,
-- ucp_Mandaic,
-+ ucp_Batak = G_UNICODE_SCRIPT_BATAK,
-+ ucp_Brahmi = G_UNICODE_SCRIPT_BRAHMI,
-+ ucp_Mandaic = G_UNICODE_SCRIPT_MANDAIC,
- /* New for Unicode 6.1.0: */
-- ucp_Chakma,
-- ucp_Meroitic_Cursive,
-- ucp_Meroitic_Hieroglyphs,
-- ucp_Miao,
-- ucp_Sharada,
-- ucp_Sora_Sompeng,
-- ucp_Takri
-+ ucp_Chakma = G_UNICODE_SCRIPT_CHAKMA,
-+ ucp_Meroitic_Cursive = G_UNICODE_SCRIPT_MEROITIC_CURSIVE,
-+ ucp_Meroitic_Hieroglyphs = G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS,
-+ ucp_Miao = G_UNICODE_SCRIPT_MIAO,
-+ ucp_Sharada = G_UNICODE_SCRIPT_SHARADA,
-+ ucp_Sora_Sompeng = G_UNICODE_SCRIPT_SORA_SOMPENG,
-+ ucp_Takri = G_UNICODE_SCRIPT_TAKRI,
- };
-
- #endif
---
-1.7.5.1.217.g4e3aa.dirty
-
diff --git a/glib/update-pcre/update.sh b/glib/update-pcre/update.sh
deleted file mode 100644
index 69d7f8aa7..000000000
--- a/glib/update-pcre/update.sh
+++ /dev/null
@@ -1,124 +0,0 @@
-#! /bin/sh
-
-set -e
-
-IN="../update-pcre"
-PCRE=$1
-
-if [ "x$PCRE" = x ] || [ "x$PCRE" = x--help ] || [ "x$PCRE" = x-h ]; then
- cat >&2 << EOF
-
-$0 PCRE-DIR
-
- Updates the local PCRE copy with a different version of the library,
- contained in the directory PCRE-DIR.
-
- This will delete the content of the local pcre directory, copy the
- necessary files from PCRE-DIR, and generate other needed files, such
- as Makefile.am
-EOF
- exit
-fi
-
-if [ ! -f gregex.h ]; then
- echo "This script should be executed from the directory containing gregex.c." 2> /dev/null
- exit 1
-fi
-
-if [ ! -f "${PCRE}/Makefile.in" ] || [ ! -f "${PCRE}/pcre_compile.c" ]; then
- echo "'${PCRE}' does not contain a valid PCRE version." 2> /dev/null
- exit 1
-fi
-
-
-echo "Deleting old PCRE library"
-mv pcre/.svn tmp-pcre-svn
-rm -R pcre 2> /dev/null
-mkdir pcre
-cd pcre
-
-# pcre_chartables.c is generated by dfatables.
-# We do not want to compile and execute dfatables.c every time, because
-# this could be a problem (e.g. when cross-compiling), so now generate
-# the file and then distribute it with GRegex.
-echo "Generating pcre_chartables.c"
-cp -R "${PCRE}" tmp-build
-(
-cd tmp-build || exit 1
-./configure --enable-utf8 --enable-unicode-properties --disable-cpp > /dev/null
-make pcre_chartables.c > /dev/null
-cat > ../pcre_chartables.c << \EOF
-/* This file is autogenerated by ../update-pcre/update.sh during
- * the update of the local copy of PCRE.
- */
-EOF
-cat pcre_chartables.c >> ../pcre_chartables.c
-)
-rm -R tmp-build
-
-# Compiled C files.
-echo "Generating makefiles"
-all_files=$(awk '/^OBJ = /, /^\\s*$/ ' \
- '{' \
- 'sub("^OBJ = ", "");' \
- 'sub(".@OBJEXT@[[:blank:]]*\\\\\\\\", "");' \
- 'sub("\\\\$\\\\(POSIX_OBJ\\\\)", "");' \
- 'print;' \
- '}' \
- "${PCRE}/Makefile.in")
-
-# Headers.
-included_files="pcre.h pcre_internal.h ucp.h ucpinternal.h"
-
-# Generate Makefile.am.
-cat $IN/Makefile.am-1 > Makefile.am
-for name in $all_files; do
- echo " $name.c \\" >> Makefile.am
- if [ "${name}" != pcre_chartables ]; then
- # pcre_chartables.c is a generated file.
- cp "${PCRE}/${name}.c" .
- fi
-done
-for f in $included_files; do
- echo " $f \\" >> Makefile.am
- cp "${PCRE}/${f}" .
-done
-cat $IN/Makefile.am-2 >> Makefile.am
-
-echo "Patching PCRE"
-
-# Copy the license.
-cp "${PCRE}/COPYING" .
-
-# Use glib for memory allocation.
-patch > /dev/null < $IN/memory.patch
-
-# Copy the modified version of pcre_valid_utf8.c.
-cp $IN/pcre_valid_utf8.c .
-
-# Copy the modified version of pcre_ucp_searchfuncs.c that uses glib
-# for Unicode properties.
-cp $IN/pcre_ucp_searchfuncs.c .
-patch > /dev/null < $IN/ucp.patch
-
-# Remove the digitab array in pcre_compile.c.
-patch > /dev/null < $IN/digitab.patch
-sed -i -e 's/(digitab\[\(.*\)\] & ctype_digit)/g_ascii_isdigit(\1)/' pcre_compile.c
-sed -i -e 's/(digitab\[\(.*\)\] & ctype_xdigit)/g_ascii_isxdigit(\1)/' pcre_compile.c
-
-# Reduce the number of relocations.
-python $IN/make_utt.py
-patch > /dev/null < $IN/utt.patch
-patch > /dev/null < $IN/table-reduction.patch
-
-# Copy back the old SVN directory.
-mv ../tmp-pcre-svn .svn
-
-
-cat << EOF
-
-Update completed. You now should check that everything is working.
-Remember to update the regex syntax doc with the new features
-(docs/reference/glib/regex-syntax.sgml) and to run the tests.
-EOF
-
diff --git a/gmodule/gmodule-dl.c b/gmodule/gmodule-dl.c
index bb2df6836..c1408212a 100644
--- a/gmodule/gmodule-dl.c
+++ b/gmodule/gmodule-dl.c
@@ -28,6 +28,7 @@
#include "config.h"
#include <dlfcn.h>
+#include <glib.h>
/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systems? */
@@ -73,11 +74,46 @@
#endif /* RTLD_GLOBAL */
-/* --- functions --- */
-static gchar*
+/* According to POSIX.1-2001, dlerror() is not necessarily thread-safe
+ * (see https://pubs.opengroup.org/onlinepubs/009695399/), and so must be
+ * called within the same locked section as the dlopen()/dlsym() call which
+ * may have caused an error.
+ *
+ * However, some libc implementations, such as glibc, implement dlerror() using
+ * thread-local storage, so are thread-safe. As of early 2021:
+ * - glibc is thread-safe: https://github.com/bminor/glibc/blob/HEAD/dlfcn/libc_dlerror_result.c
+ * - uclibc-ng is not thread-safe: https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/ldso/libdl/libdl.c?id=132decd2a043d0ccf799f42bf89f3ae0c11e95d5#n1075
+ * - Other libc implementations have not been checked, and no problems have
+ * been reported with them in 10 years, so default to assuming that they
+ * don’t need additional thread-safety from GLib
+ */
+#if defined(__UCLIBC__)
+G_LOCK_DEFINE_STATIC (errors);
+#else
+#define DLERROR_IS_THREADSAFE 1
+#endif
+
+static void
+lock_dlerror (void)
+{
+#ifndef DLERROR_IS_THREADSAFE
+ G_LOCK (errors);
+#endif
+}
+
+static void
+unlock_dlerror (void)
+{
+#ifndef DLERROR_IS_THREADSAFE
+ G_UNLOCK (errors);
+#endif
+}
+
+/* This should be called with lock_dlerror() held */
+static const gchar *
fetch_dlerror (gboolean replace_null)
{
- gchar *msg = dlerror ();
+ const gchar *msg = dlerror ();
/* make sure we always return an error message != NULL, if
* expected to do so. */
@@ -95,10 +131,12 @@ _g_module_open (const gchar *file_name,
{
gpointer handle;
+ lock_dlerror ();
handle = dlopen (file_name,
(bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
if (!handle)
g_module_set_error (fetch_dlerror (TRUE));
+ unlock_dlerror ();
return handle;
}
@@ -119,6 +157,7 @@ _g_module_self (void)
* always returns 'undefined symbol'. Only if RTLD_DEFAULT or
* NULL is given, dlsym returns an appropriate pointer.
*/
+ lock_dlerror ();
#if defined(__BIONIC__)
handle = RTLD_DEFAULT;
#else
@@ -126,6 +165,7 @@ _g_module_self (void)
#endif
if (!handle)
g_module_set_error (fetch_dlerror (TRUE));
+ unlock_dlerror ();
return handle;
}
@@ -137,8 +177,10 @@ _g_module_close (gpointer handle)
if (handle != RTLD_DEFAULT)
#endif
{
+ lock_dlerror ();
if (dlclose (handle) != 0)
- g_module_set_error (fetch_dlerror (TRUE));
+ g_module_set_error (fetch_dlerror (TRUE));
+ unlock_dlerror ();
}
}
@@ -147,13 +189,15 @@ _g_module_symbol (gpointer handle,
const gchar *symbol_name)
{
gpointer p;
- gchar *msg;
+ const gchar *msg;
+ lock_dlerror ();
fetch_dlerror (FALSE);
p = dlsym (handle, symbol_name);
msg = fetch_dlerror (FALSE);
if (msg)
g_module_set_error (msg);
+ unlock_dlerror ();
return p;
}
diff --git a/gobject/gboxed.c b/gobject/gboxed.c
index 194251383..ae48df566 100644
--- a/gobject/gboxed.c
+++ b/gobject/gboxed.c
@@ -175,6 +175,7 @@ G_DEFINE_BOXED_TYPE (GChecksum, g_checksum, g_checksum_copy, g_checksum_free)
G_DEFINE_BOXED_TYPE (GUri, g_uri, g_uri_ref, g_uri_unref)
G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref)
+G_DEFINE_BOXED_TYPE (GPatternSpec, g_pattern_spec, g_pattern_spec_copy, g_pattern_spec_free);
/* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */
GType
diff --git a/gobject/glib-types.h b/gobject/glib-types.h
index cdccdaab4..808284622 100644
--- a/gobject/glib-types.h
+++ b/gobject/glib-types.h
@@ -315,6 +315,15 @@ typedef gsize GType;
*/
#define G_TYPE_TREE (g_tree_get_type ())
+/**
+ * G_TYPE_PATTERN_SPEC:
+ *
+ * The #GType for #GPatternSpec.
+ *
+ * Since: 2.70
+ */
+#define G_TYPE_PATTERN_SPEC (g_pattern_spec_get_type ())
+
GLIB_AVAILABLE_IN_ALL
GType g_date_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_ALL
@@ -375,6 +384,8 @@ GLIB_AVAILABLE_IN_2_66
GType g_uri_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_2_68
GType g_tree_get_type (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_2_70
+GType g_pattern_spec_get_type (void) G_GNUC_CONST;
GLIB_DEPRECATED_FOR('G_TYPE_VARIANT')
GType g_variant_get_gtype (void) G_GNUC_CONST;
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 750a7d120..a88682360 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -3186,6 +3186,62 @@ gpointer
}
/**
+ * g_object_take_ref: (skip)
+ * @object: (type GObject.Object): a #GObject
+ *
+ * If @object is floating, sink it. Otherwise, do nothing.
+ *
+ * In other words, this function will convert a floating reference (if
+ * present) into a full reference.
+ *
+ * Typically you want to use g_object_ref_sink() in order to
+ * automatically do the correct thing with respect to floating or
+ * non-floating references, but there is one specific scenario where
+ * this function is helpful.
+ *
+ * The situation where this function is helpful is when creating an API
+ * that allows the user to provide a callback function that returns a
+ * GObject. We certainly want to allow the user the flexibility to
+ * return a non-floating reference from this callback (for the case
+ * where the object that is being returned already exists).
+ *
+ * At the same time, the API style of some popular GObject-based
+ * libraries (such as Gtk) make it likely that for newly-created GObject
+ * instances, the user can be saved some typing if they are allowed to
+ * return a floating reference.
+ *
+ * Using this function on the return value of the user's callback allows
+ * the user to do whichever is more convenient for them. The caller will
+ * alway receives exactly one full reference to the value: either the
+ * one that was returned in the first place, or a floating reference
+ * that has been converted to a full reference.
+ *
+ * This function has an odd interaction when combined with
+ * g_object_ref_sink() running at the same time in another thread on
+ * the same #GObject instance. If g_object_ref_sink() runs first then
+ * the result will be that the floating reference is converted to a hard
+ * reference. If g_object_take_ref() runs first then the result will be
+ * that the floating reference is converted to a hard reference and an
+ * additional reference on top of that one is added. It is best to avoid
+ * this situation.
+ *
+ * Since: 2.70
+ *
+ * Returns: (type GObject.Object) (transfer full): @object
+ */
+gpointer
+g_object_take_ref (gpointer _object)
+{
+ GObject *object = _object;
+ g_return_val_if_fail (G_IS_OBJECT (object), object);
+ g_return_val_if_fail (g_atomic_int_get (&object->ref_count) >= 1, object);
+
+ floating_flag_handler (object, -1);
+
+ return object;
+}
+
+/**
* g_object_force_floating:
* @object: a #GObject
*
@@ -3319,7 +3375,8 @@ g_object_add_toggle_ref (GObject *object,
* @notify: a function to call when this reference is the
* last reference to the object, or is no longer
* the last reference.
- * @data: data to pass to @notify
+ * @data: (nullable): data to pass to @notify, or %NULL to
+ * match any toggle refs with the @notify argument.
*
* Removes a reference added with g_object_add_toggle_ref(). The
* reference count of the object is decreased by one.
@@ -3345,7 +3402,7 @@ g_object_remove_toggle_ref (GObject *object,
for (i = 0; i < tstack->n_toggle_refs; i++)
if (tstack->toggle_refs[i].notify == notify &&
- tstack->toggle_refs[i].data == data)
+ (tstack->toggle_refs[i].data == data || data == NULL))
{
found_one = TRUE;
tstack->n_toggle_refs -= 1;
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 125aed876..86e2b7de1 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -28,11 +28,6 @@
#include <gobject/gsignal.h>
#include <gobject/gboxed.h>
-#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
-/* for glib_typeof */
-#include <type_traits>
-#endif
-
G_BEGIN_DECLS
/* --- type macros --- */
@@ -499,6 +494,8 @@ GLIB_AVAILABLE_IN_ALL
gboolean g_object_is_floating (gpointer object);
GLIB_AVAILABLE_IN_ALL
gpointer g_object_ref_sink (gpointer object);
+GLIB_AVAILABLE_IN_2_70
+gpointer g_object_take_ref (gpointer object);
GLIB_AVAILABLE_IN_ALL
gpointer g_object_ref (gpointer object);
GLIB_AVAILABLE_IN_ALL
@@ -518,7 +515,7 @@ GLIB_AVAILABLE_IN_ALL
void g_object_remove_weak_pointer (GObject *object,
gpointer *weak_pointer_location);
-#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
+#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56
/* Make reference APIs type safe with macros */
#define g_object_ref(Obj) ((glib_typeof (Obj)) (g_object_ref) (Obj))
#define g_object_ref_sink(Obj) ((glib_typeof (Obj)) (g_object_ref_sink) (Obj))
diff --git a/gobject/gsignal.h b/gobject/gsignal.h
index 64aa9d6a8..b027f54c0 100644
--- a/gobject/gsignal.h
+++ b/gobject/gsignal.h
@@ -87,8 +87,11 @@ typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
* value returned by the last callback.
*
* Returns: The accumulator function returns whether the signal emission
- * should be aborted. Returning %FALSE means to abort the
- * current emission and %TRUE is returned for continuation.
+ * should be aborted. Returning %TRUE will continue with
+ * the signal emission. Returning %FALSE will abort the current emission.
+ * Since 2.62, returning %FALSE will skip to the CLEANUP stage. In this case,
+ * emission will occur as normal in the CLEANUP stage and the handler's
+ * return value will be accumulated.
*/
typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint,
GValue *return_accu,
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 94e23b814..2cdbe7ce4 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -1100,7 +1100,8 @@ type_data_make_W (TypeNode *node,
vtable = pnode->data->common.value_table;
else
{
- static const GTypeValueTable zero_vtable = { NULL, };
+ static const GTypeValueTable zero_vtable =
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
value_table = &zero_vtable;
}
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 621c6514d..5f9766978 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -2108,7 +2108,7 @@ type_name##_get_type (void) \
/* Only use this in non-C++ on GCC >= 2.7, except for Darwin/ppc64.
* See https://bugzilla.gnome.org/show_bug.cgi?id=647145
*/
-#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) && !(defined (__APPLE__) && defined (__ppc64__))
+#if !defined (__cplusplus) && (G_GNUC_CHECK_VERSION(2, 7)) && !(defined (__APPLE__) && defined (__ppc64__))
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
static GType type_name##_get_type_once (void); \
\
diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c
index 732ea2b08..60d7b6647 100644
--- a/gobject/gvaluetypes.c
+++ b/gobject/gvaluetypes.c
@@ -1024,7 +1024,7 @@ g_value_get_double (const GValue *value)
* @value: a valid #GValue of type %G_TYPE_STRING
* @v_string: (nullable): caller-owned string to be duplicated for the #GValue
*
- * Set the contents of a %G_TYPE_STRING #GValue to @v_string.
+ * Set the contents of a %G_TYPE_STRING #GValue to a copy of @v_string.
*/
void
g_value_set_string (GValue *value,
diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c
index 61002f4fb..e63dd1e6e 100644
--- a/gobject/tests/binding.c
+++ b/gobject/tests/binding.c
@@ -574,8 +574,7 @@ binding_chain (void)
BindingSource *c = g_object_new (binding_source_get_type (), NULL);
GBinding *binding_1, *binding_2;
- g_test_bug_base ("http://bugzilla.gnome.org/");
- g_test_bug ("621782");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=621782");
/* A -> B, B -> C */
binding_1 = g_object_bind_property (a, "foo", b, "foo", G_BINDING_BIDIRECTIONAL);
@@ -794,7 +793,7 @@ binding_unbind_multiple (void)
GBinding *binding;
guint i;
- g_test_bug ("1373");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1373");
binding = g_object_bind_property (source, "foo",
target, "bar",
@@ -1081,8 +1080,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/issues/");
-
g_test_add_func ("/binding/default", binding_default);
g_test_add_func ("/binding/canonicalisation", binding_canonicalisation);
g_test_add_func ("/binding/bidirectional", binding_bidirectional);
diff --git a/gobject/tests/boxed.c b/gobject/tests/boxed.c
index 0c8872a82..f961a2f87 100644
--- a/gobject/tests/boxed.c
+++ b/gobject/tests/boxed.c
@@ -645,6 +645,29 @@ test_boxed_tree (void)
g_value_unset (&value);
}
+static void
+test_boxed_pattern_spec (void)
+{
+ GPatternSpec *ps, *ps2;
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, G_TYPE_PATTERN_SPEC);
+ g_assert_true (G_VALUE_HOLDS_BOXED (&value));
+
+ ps = g_pattern_spec_new ("*abc*?cde");
+ g_value_take_boxed (&value, ps);
+
+ ps2 = g_value_get_boxed (&value);
+ g_assert_true (ps == ps2);
+
+ ps2 = g_value_dup_boxed (&value);
+ g_assert_true (ps != ps2);
+ g_assert_true (g_pattern_spec_equal (ps, ps2));
+ g_pattern_spec_free (ps2);
+
+ g_value_unset (&value);
+}
+
int
main (int argc, char *argv[])
{
@@ -675,6 +698,7 @@ main (int argc, char *argv[])
g_test_add_func ("/boxed/thread", test_boxed_thread);
g_test_add_func ("/boxed/checksum", test_boxed_checksum);
g_test_add_func ("/boxed/tree", test_boxed_tree);
+ g_test_add_func ("/boxed/patternspec", test_boxed_pattern_spec);
return g_test_run ();
}
diff --git a/gobject/tests/ifaceproperties.c b/gobject/tests/ifaceproperties.c
index 4d0053eea..cb7acf4ec 100644
--- a/gobject/tests/ifaceproperties.c
+++ b/gobject/tests/ifaceproperties.c
@@ -618,7 +618,7 @@ test_not_overridden (void)
if (!g_test_undefined ())
return;
- g_test_bug ("637738");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=637738");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*Base2Object doesn't implement property 'prop3' from interface 'TestIface'*");
@@ -632,7 +632,6 @@ int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/interface/properties/set", test_set);
g_test_add_func ("/interface/properties/notify", test_notify);
diff --git a/gobject/tests/object.c b/gobject/tests/object.c
index 3e85995c2..2519b0034 100644
--- a/gobject/tests/object.c
+++ b/gobject/tests/object.c
@@ -122,7 +122,7 @@ test_object_constructor_infanticide (void)
GObject *obj;
int i;
- g_test_bug ("661576");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576");
for (i = 0; i < 1000; i++)
{
@@ -142,7 +142,6 @@ int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton);
g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide);
diff --git a/gobject/tests/properties.c b/gobject/tests/properties.c
index 297713d5a..3695ee123 100644
--- a/gobject/tests/properties.c
+++ b/gobject/tests/properties.c
@@ -322,7 +322,7 @@ properties_construct (void)
gboolean b;
gchar *s;
- g_test_bug ("630357");
+ g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=630357");
/* more than 16 args triggers a realloc in g_object_new_valist() */
obj = g_object_new (test_object_get_type (),
@@ -638,8 +638,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("http://bugzilla.gnome.org/");
-
g_test_add_func ("/properties/install", properties_install);
g_test_add_func ("/properties/notify", properties_notify);
g_test_add_func ("/properties/notify-queue", properties_notify_queue);
diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c
index c6f4d5127..04645e14a 100644
--- a/gobject/tests/reference.c
+++ b/gobject/tests/reference.c
@@ -322,6 +322,20 @@ test_initially_unowned (void)
g_object_ref_sink (obj);
g_object_unref (obj);
+
+ obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
+ g_assert_true (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_take_ref (obj);
+ g_assert_false (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_take_ref (obj);
+ g_assert_false (g_object_is_floating (obj));
+ g_assert_cmpint (obj->ref_count, ==, 1);
+
+ g_object_unref (obj);
}
static void
diff --git a/meson.build b/meson.build
index a0223ce5b..1b54fdcae 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
project('glib', 'c', 'cpp',
- version : '2.68.4',
+ version : '2.69.0',
# NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
meson_version : '>= 0.49.2',
default_options : [
@@ -14,18 +14,23 @@ cxx = meson.get_compiler('cpp')
cc_can_run = not meson.is_cross_build() or meson.has_exe_wrapper()
-if cc.get_id() == 'msvc'
+if cc.get_argument_syntax() == 'msvc'
# Ignore several spurious warnings for things glib does very commonly
+ # (also for clang-cl)
+ add_project_arguments('/FImsvc_recommended_pragmas.h',language : 'c')
+endif
+
+if cc.get_id() == 'msvc'
# If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
# NOTE: Only add warnings here if you are sure they're spurious
add_project_arguments('/wd4035', '/wd4715', '/wd4116',
- '/wd4046', '/wd4068', '/wo4090', '/FImsvc_recommended_pragmas.h',language : 'c')
+ '/wd4046', '/wd4068', '/wo4090',language : 'c')
+ # Set the input and exec encoding to utf-8, like is the default with GCC
+ add_project_arguments(cc.get_supported_arguments(['/utf-8']), language: 'c')
# Disable SAFESEH with MSVC for plugins and libs that use external deps that
# are built with MinGW
noseh_link_args = ['/SAFESEH:NO']
- # Set the input and exec encoding to utf-8, like is the default with GCC
- add_project_arguments(cc.get_supported_arguments(['/utf-8']), language: 'c')
else
noseh_link_args = []
# -mms-bitfields vs -fnative-struct ?
@@ -1185,6 +1190,15 @@ if cc.links('''#ifndef _GNU_SOURCE
glib_conf.set('HAVE_LANGINFO_ABALTMON', 1)
endif
+# Check for nl_langinfo and _NL_TIME_CODESET
+if cc.links('''#include <langinfo.h>
+ int main (int argc, char ** argv) {
+ char *codeset = nl_langinfo (_NL_TIME_CODESET);
+ return 0;
+ }''', name : 'nl_langinfo and _NL_TIME_CODESET')
+ glib_conf.set('HAVE_LANGINFO_TIME_CODESET', 1)
+endif
+
# Check if C compiler supports the 'signed' keyword
if not cc.compiles('''signed char x;''', name : 'signed')
glib_conf.set('signed', '/* NOOP */')
@@ -1965,46 +1979,37 @@ else
endif
endif
-if get_option('internal_pcre')
- pcre = []
- use_system_pcre = false
-else
- pcre = dependency('libpcre', version: '>= 8.31', required : false) # Should check for Unicode support, too. FIXME
- if not pcre.found()
- if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
- # MSVC: Search for the PCRE library by the configuration, which corresponds
- # to the output of CMake builds of PCRE. Note that debugoptimized
- # is really a Release build with .PDB files.
- if vs_crt == 'debug'
- pcre = cc.find_library('pcred', required : false)
- else
- pcre = cc.find_library('pcre', required : false)
- endif
+pcre = dependency('libpcre', version: '>= 8.31', required : false) # Should check for Unicode support, too. FIXME
+if not pcre.found()
+ if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
+ # MSVC: Search for the PCRE library by the configuration, which corresponds
+ # to the output of CMake builds of PCRE. Note that debugoptimized
+ # is really a Release build with .PDB files.
+ if vs_crt == 'debug'
+ pcre = cc.find_library('pcred', required : false)
+ else
+ pcre = cc.find_library('pcre', required : false)
endif
endif
- use_system_pcre = pcre.found()
endif
-glib_conf.set('USE_SYSTEM_PCRE', use_system_pcre)
-
-use_pcre_static_flag = false
-if host_system == 'windows'
- if not use_system_pcre
- use_pcre_static_flag = true
- else
- pcre_static = cc.links('''#define PCRE_STATIC
- #include <pcre.h>
- int main() {
- void *p = NULL;
- pcre_free(p);
- return 0;
- }''',
- dependencies: pcre,
- name : 'Windows system PCRE is a static build')
- if pcre_static
- use_pcre_static_flag = true
- endif
- endif
+# Try again with the fallback
+if not pcre.found()
+ pcre = dependency('libpcre', required : true, fallback : ['libpcre', 'pcre_dep'])
+ use_pcre_static_flag = true
+elif host_system == 'windows'
+ pcre_static = cc.links('''#define PCRE_STATIC
+ #include <pcre.h>
+ int main() {
+ void *p = NULL;
+ pcre_free(p);
+ return 0;
+ }''',
+ dependencies: pcre,
+ name : 'Windows system PCRE is a static build')
+ use_pcre_static_flag = pcre_static
+else
+ use_pcre_static_flag = false
endif
libm = cc.find_library('m', required : false)
@@ -2038,13 +2043,13 @@ endif
# FIXME: glib-gettext.m4 has much more checks to detect broken/uncompatible
# implementations. This could be extended if issues are found in some platforms.
libintl_deps = []
-if cc.has_function('ngettext')
+if cc.has_function('ngettext', args : osx_ldflags)
have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset')
else
# First just find the bare library.
libintl = cc.find_library('intl', required : false)
# The bare library probably won't link without help if it's static.
- if libintl.found() and not cc.has_function('ngettext', dependencies : libintl)
+ if libintl.found() and not cc.has_function('ngettext', args : osx_ldflags, dependencies : libintl)
libintl_iconv = cc.find_library('iconv', required : false)
# libintl supports different threading APIs, which may not
# require additional flags, but it defaults to using pthreads if
@@ -2054,10 +2059,10 @@ else
# also defining the macros with the -pthread flag.
libintl_pthread = cc.find_library('pthread', required : false)
# Try linking with just libiconv.
- if libintl_iconv.found() and cc.has_function('ngettext', dependencies : [libintl, libintl_iconv])
+ if libintl_iconv.found() and cc.has_function('ngettext', args : osx_ldflags, dependencies : [libintl, libintl_iconv])
libintl_deps += [libintl_iconv]
# Then also try linking with pthreads.
- elif libintl_iconv.found() and libintl_pthread.found() and cc.has_function('ngettext', dependencies : [libintl, libintl_iconv, libintl_pthread])
+ elif libintl_iconv.found() and libintl_pthread.found() and cc.has_function('ngettext', args : osx_ldflags, dependencies : [libintl, libintl_iconv, libintl_pthread])
libintl_deps += [libintl_iconv, libintl_pthread]
else
libintl = disabler()
@@ -2069,7 +2074,7 @@ else
have_bind_textdomain_codeset = true # proxy-libintl supports it
else
libintl_deps = [libintl] + libintl_deps
- have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset',
+ have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset', args : osx_ldflags,
dependencies : libintl_deps)
endif
endif
diff --git a/meson_options.txt b/meson_options.txt
index 072765361..6cd7bc90a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -34,11 +34,6 @@ option('libmount',
value : 'auto',
description : 'build with libmount support')
-option('internal_pcre',
- type : 'boolean',
- value : false,
- description : 'whether to use internal PCRE')
-
option('man',
type : 'boolean',
value : false,
diff --git a/msvc_recommended_pragmas.h b/msvc_recommended_pragmas.h
index e70698712..051a02ae4 100644
--- a/msvc_recommended_pragmas.h
+++ b/msvc_recommended_pragmas.h
@@ -1,10 +1,11 @@
#ifndef _MSC_VER
-#pragma error "This header is for Microsoft VC only."
+#pragma error "This header is for Microsoft VC or clang-cl only."
#endif /* _MSC_VER */
/* Make MSVC more pedantic, this is a recommended pragma list
* from _Win32_Programming_ by Rector and Newcomer.
*/
+#ifndef __clang__
#pragma warning(error:4002) /* too many actual parameters for macro */
#pragma warning(error:4003) /* not enough actual parameters for macro */
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
@@ -33,6 +34,7 @@
#pragma warning(disable:4305) /* No truncation from int to char warnings */
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
+#endif /* __clang__ */
/* work around Microsoft's premature attempt to deprecate the C-Library */
#define _CRT_SECURE_NO_WARNINGS
diff --git a/po/he.po b/po/he.po
index c81a86b82..b0fd340bc 100644
--- a/po/he.po
+++ b/po/he.po
@@ -14,16 +14,17 @@ msgid ""
msgstr ""
"Project-Id-Version: glib.HEAD.he\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2020-08-22 13:31+0000\n"
-"PO-Revision-Date: 2020-09-28 23:42+0300\n"
-"Last-Translator: Yosef Or Boczko <yoseforb@gmail.com>\n"
+"POT-Creation-Date: 2021-03-22 11:48+0000\n"
+"PO-Revision-Date: 2021-05-28 22:57+0300\n"
+"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <yoseforb@gmail.com>\n"
"Language: he\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"X-Generator: Gtranslator 3.36.0\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? "
+"2 : 3);\n"
+"X-Generator: Poedit 2.4.3\n"
#: gio/gapplication.c:500
msgid "GApplication options"
@@ -62,90 +63,90 @@ msgstr "Print version"
msgid "Print version information and exit"
msgstr "Print version information and exit"
-#: gio/gapplication-tool.c:52
+#: gio/gapplication-tool.c:53
msgid "List applications"
msgstr "List applications"
-#: gio/gapplication-tool.c:53
+#: gio/gapplication-tool.c:54
msgid "List the installed D-Bus activatable applications (by .desktop files)"
msgstr "List the installed D-Bus activatable applications (by .desktop files)"
-#: gio/gapplication-tool.c:55
+#: gio/gapplication-tool.c:57
msgid "Launch an application"
msgstr "Launch an application"
-#: gio/gapplication-tool.c:56
+#: gio/gapplication-tool.c:58
msgid "Launch the application (with optional files to open)"
msgstr "Launch the application (with optional files to open)"
-#: gio/gapplication-tool.c:57
+#: gio/gapplication-tool.c:59
msgid "APPID [FILE…]"
msgstr "APPID [FILE…]"
-#: gio/gapplication-tool.c:59
+#: gio/gapplication-tool.c:61
msgid "Activate an action"
msgstr "Activate an action"
-#: gio/gapplication-tool.c:60
+#: gio/gapplication-tool.c:62
msgid "Invoke an action on the application"
msgstr "Invoke an action on the application"
-#: gio/gapplication-tool.c:61
+#: gio/gapplication-tool.c:63
msgid "APPID ACTION [PARAMETER]"
msgstr "APPID ACTION [PARAMETER]"
-#: gio/gapplication-tool.c:63
+#: gio/gapplication-tool.c:65
msgid "List available actions"
msgstr "List available actions"
-#: gio/gapplication-tool.c:64
+#: gio/gapplication-tool.c:66
msgid "List static actions for an application (from .desktop file)"
msgstr "List static actions for an application (from .desktop file)"
-#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71
+#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73
msgid "APPID"
msgstr "APPID"
-#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102
+#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106
#: gio/gio-tool.c:224
msgid "COMMAND"
msgstr "COMMAND"
-#: gio/gapplication-tool.c:70
+#: gio/gapplication-tool.c:72
msgid "The command to print detailed help for"
msgstr "The command to print detailed help for"
-#: gio/gapplication-tool.c:71
+#: gio/gapplication-tool.c:73
msgid "Application identifier in D-Bus format (eg: org.example.viewer)"
msgstr "Application identifier in D-Bus format (eg: org.example.viewer)"
-#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738
+#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738
#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772
#: gio/gresource-tool.c:500 gio/gresource-tool.c:566
msgid "FILE"
msgstr "FILE"
-#: gio/gapplication-tool.c:72
+#: gio/gapplication-tool.c:74
msgid "Optional relative or absolute filenames, or URIs to open"
msgstr "Optional relative or absolute filenames, or URIs to open"
-#: gio/gapplication-tool.c:73
+#: gio/gapplication-tool.c:75
msgid "ACTION"
msgstr "ACTION"
-#: gio/gapplication-tool.c:73
+#: gio/gapplication-tool.c:75
msgid "The action name to invoke"
msgstr "The action name to invoke"
-#: gio/gapplication-tool.c:74
+#: gio/gapplication-tool.c:76
msgid "PARAMETER"
msgstr "PARAMETER"
-#: gio/gapplication-tool.c:74
+#: gio/gapplication-tool.c:76
msgid "Optional parameter to the action invocation, in GVariant format"
msgstr "Optional parameter to the action invocation, in GVariant format"
-#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659
+#: gio/gapplication-tool.c:98 gio/gresource-tool.c:531 gio/gsettings-tool.c:659
#, c-format
msgid ""
"Unknown command %s\n"
@@ -154,26 +155,26 @@ msgstr ""
"Unknown command %s\n"
"\n"
-#: gio/gapplication-tool.c:101
+#: gio/gapplication-tool.c:103
msgid "Usage:\n"
msgstr "Usage:\n"
-#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556
+#: gio/gapplication-tool.c:116 gio/gresource-tool.c:556
#: gio/gsettings-tool.c:694
msgid "Arguments:\n"
msgstr "Arguments:\n"
-#: gio/gapplication-tool.c:133 gio/gio-tool.c:224
+#: gio/gapplication-tool.c:135 gio/gio-tool.c:224
msgid "[ARGS…]"
msgstr "[ARGS…]"
-#: gio/gapplication-tool.c:134
+#: gio/gapplication-tool.c:136
#, c-format
msgid "Commands:\n"
msgstr "Commands:\n"
#. Translators: do not translate 'help', but please translate 'COMMAND'.
-#: gio/gapplication-tool.c:146
+#: gio/gapplication-tool.c:148
#, c-format
msgid ""
"Use “%s help COMMAND” to get detailed help.\n"
@@ -182,7 +183,7 @@ msgstr ""
"Use “%s help COMMAND” to get detailed help.\n"
"\n"
-#: gio/gapplication-tool.c:165
+#: gio/gapplication-tool.c:167
#, c-format
msgid ""
"%s command requires an application id to directly follow\n"
@@ -191,13 +192,13 @@ msgstr ""
"%s command requires an application id to directly follow\n"
"\n"
-#: gio/gapplication-tool.c:171
+#: gio/gapplication-tool.c:173
#, c-format
msgid "invalid application id: “%s”\n"
msgstr "invalid application id: “%s”\n"
#. Translators: %s is replaced with a command name like 'list-actions'
-#: gio/gapplication-tool.c:182
+#: gio/gapplication-tool.c:184
#, c-format
msgid ""
"“%s” takes no arguments\n"
@@ -206,21 +207,21 @@ msgstr ""
"“%s” takes no arguments\n"
"\n"
-#: gio/gapplication-tool.c:266
+#: gio/gapplication-tool.c:268
#, c-format
msgid "unable to connect to D-Bus: %s\n"
msgstr "unable to connect to D-Bus: %s\n"
-#: gio/gapplication-tool.c:286
+#: gio/gapplication-tool.c:288
#, c-format
msgid "error sending %s message to application: %s\n"
msgstr "error sending %s message to application: %s\n"
-#: gio/gapplication-tool.c:317
+#: gio/gapplication-tool.c:319
msgid "action name must be given after application id\n"
msgstr "action name must be given after application id\n"
-#: gio/gapplication-tool.c:325
+#: gio/gapplication-tool.c:327
#, c-format
msgid ""
"invalid action name: “%s”\n"
@@ -229,25 +230,25 @@ msgstr ""
"invalid action name: “%s”\n"
"action names must consist of only alphanumerics, “-” and “.”\n"
-#: gio/gapplication-tool.c:344
+#: gio/gapplication-tool.c:346
#, c-format
msgid "error parsing action parameter: %s\n"
msgstr "error parsing action parameter: %s\n"
-#: gio/gapplication-tool.c:356
+#: gio/gapplication-tool.c:358
msgid "actions accept a maximum of one parameter\n"
msgstr "actions accept a maximum of one parameter\n"
-#: gio/gapplication-tool.c:411
+#: gio/gapplication-tool.c:413
msgid "list-actions command takes only the application id"
msgstr "list-actions command takes only the application id"
-#: gio/gapplication-tool.c:421
+#: gio/gapplication-tool.c:423
#, c-format
msgid "unable to find desktop file for application %s\n"
msgstr "unable to find desktop file for application %s\n"
-#: gio/gapplication-tool.c:466
+#: gio/gapplication-tool.c:468
#, c-format
msgid ""
"unrecognised command: %s\n"
@@ -257,8 +258,8 @@ msgstr ""
"\n"
#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498
-#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617
-#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049
+#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:646
+#: gio/ginputstream.c:1048 gio/goutputstream.c:223 gio/goutputstream.c:1049
#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277
#, c-format
msgid "Too large count value passed to %s"
@@ -269,11 +270,11 @@ msgstr "Too large count value passed to %s"
msgid "Seek not supported on base stream"
msgstr "Seek not supported on base stream"
-#: gio/gbufferedinputstream.c:937
+#: gio/gbufferedinputstream.c:938
msgid "Cannot truncate GBufferedInputStream"
msgstr "Cannot truncate GBufferedInputStream"
-#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300
+#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1237 gio/giostream.c:300
#: gio/goutputstream.c:2198
msgid "Stream is already closed"
msgstr "Stream is already closed"
@@ -282,7 +283,7 @@ msgstr "Stream is already closed"
msgid "Truncate not supported on base stream"
msgstr "Truncate not supported on base stream"
-#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413
+#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416
#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897
#, c-format
msgid "Operation was cancelled"
@@ -301,25 +302,25 @@ msgid "Not enough space in destination"
msgstr "Not enough space in destination"
#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848
-#: gio/gdatainputstream.c:1261 glib/gconvert.c:448 glib/gconvert.c:878
-#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2461
+#: gio/gdatainputstream.c:1266 glib/gconvert.c:448 glib/gconvert.c:878
+#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470
#: glib/gutf8.c:875 glib/gutf8.c:1328
msgid "Invalid byte sequence in conversion input"
msgstr "Invalid byte sequence in conversion input"
#: gio/gcharsetconverter.c:347 glib/gconvert.c:456 glib/gconvert.c:792
-#: glib/giochannel.c:1571 glib/giochannel.c:2473
+#: glib/giochannel.c:1580 glib/giochannel.c:2482
#, c-format
msgid "Error during conversion: %s"
msgstr "Error during conversion: %s"
-#: gio/gcharsetconverter.c:445 gio/gsocket.c:1133
+#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143
msgid "Cancellable initialization not supported"
msgstr "Cancellable initialization not supported"
# *** This file should not be translated to hebrew, please only copy the english text ***
# *** Old hebrew ranslation is commented for backup sake ***
-#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1392
+#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1401
#, c-format
msgid "Conversion from character set “%s” to “%s” is not supported"
msgstr "Conversion from character set “%s” to “%s” is not supported"
@@ -329,7 +330,7 @@ msgstr "Conversion from character set “%s” to “%s” is not supported"
msgid "Could not open converter from “%s” to “%s”"
msgstr "Could not open converter from “%s” to “%s”"
-#: gio/gcontenttype.c:452
+#: gio/gcontenttype.c:454
#, c-format
msgid "%s type"
msgstr "%s type"
@@ -367,17 +368,17 @@ msgstr "Credentials spoofing is not possible on this OS"
msgid "Unexpected early end-of-stream"
msgstr "Unexpected early end-of-stream"
-#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321
+#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322
#, c-format
msgid "Unsupported key “%s” in address entry “%s”"
msgstr "Unsupported key “%s” in address entry “%s”"
-#: gio/gdbusaddress.c:171
+#: gio/gdbusaddress.c:172
#, c-format
msgid "Meaningless key/value pair combination in address entry “%s”"
msgstr "Meaningless key/value pair combination in address entry “%s”"
-#: gio/gdbusaddress.c:180
+#: gio/gdbusaddress.c:181
#, c-format
msgid ""
"Address “%s” is invalid (need exactly one of path, dir, tmpdir, or abstract "
@@ -386,28 +387,28 @@ msgstr ""
"Address “%s” is invalid (need exactly one of path, dir, tmpdir, or abstract "
"keys)"
-#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273
-#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347
+#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274
+#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348
#, c-format
msgid "Error in address “%s” — the “%s” attribute is malformed"
msgstr "Error in address “%s” — the “%s” attribute is malformed"
-#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681
+#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682
#, c-format
msgid "Unknown or unsupported transport “%s” for address “%s”"
msgstr "Unknown or unsupported transport “%s” for address “%s”"
-#: gio/gdbusaddress.c:461
+#: gio/gdbusaddress.c:462
#, c-format
msgid "Address element “%s” does not contain a colon (:)"
msgstr "Address element “%s” does not contain a colon (:)"
-#: gio/gdbusaddress.c:470
+#: gio/gdbusaddress.c:471
#, c-format
msgid "Transport name in address element “%s” must not be empty"
msgstr "Transport name in address element “%s” must not be empty"
-#: gio/gdbusaddress.c:491
+#: gio/gdbusaddress.c:492
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal "
@@ -416,14 +417,14 @@ msgstr ""
"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal "
"sign"
-#: gio/gdbusaddress.c:502
+#: gio/gdbusaddress.c:503
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"
msgstr ""
"Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"
-#: gio/gdbusaddress.c:516
+#: gio/gdbusaddress.c:517
#, c-format
msgid ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
@@ -432,7 +433,7 @@ msgstr ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
"“%s”"
-#: gio/gdbusaddress.c:588
+#: gio/gdbusaddress.c:589
#, c-format
msgid ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
@@ -441,75 +442,75 @@ msgstr ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
"“path” or “abstract” to be set"
-#: gio/gdbusaddress.c:624
+#: gio/gdbusaddress.c:625
#, c-format
msgid "Error in address “%s” — the host attribute is missing or malformed"
msgstr "Error in address “%s” — the host attribute is missing or malformed"
-#: gio/gdbusaddress.c:638
+#: gio/gdbusaddress.c:639
#, c-format
msgid "Error in address “%s” — the port attribute is missing or malformed"
msgstr "Error in address “%s” — the port attribute is missing or malformed"
-#: gio/gdbusaddress.c:652
+#: gio/gdbusaddress.c:653
#, c-format
msgid "Error in address “%s” — the noncefile attribute is missing or malformed"
msgstr ""
"Error in address “%s” — the noncefile attribute is missing or malformed"
-#: gio/gdbusaddress.c:673
+#: gio/gdbusaddress.c:674
msgid "Error auto-launching: "
msgstr "Error auto-launching: "
-#: gio/gdbusaddress.c:726
+#: gio/gdbusaddress.c:727
#, c-format
msgid "Error opening nonce file “%s”: %s"
msgstr "Error opening nonce file “%s”: %s"
-#: gio/gdbusaddress.c:745
+#: gio/gdbusaddress.c:746
#, c-format
msgid "Error reading from nonce file “%s”: %s"
msgstr "Error reading from nonce file “%s”: %s"
-#: gio/gdbusaddress.c:754
+#: gio/gdbusaddress.c:755
#, c-format
msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d"
msgstr "Error reading from nonce file “%s”, expected 16 bytes, got %d"
-#: gio/gdbusaddress.c:772
+#: gio/gdbusaddress.c:773
#, c-format
msgid "Error writing contents of nonce file “%s” to stream:"
msgstr "Error writing contents of nonce file “%s” to stream:"
-#: gio/gdbusaddress.c:981
+#: gio/gdbusaddress.c:988
msgid "The given address is empty"
msgstr "The given address is empty"
-#: gio/gdbusaddress.c:1094
+#: gio/gdbusaddress.c:1101
#, c-format
msgid "Cannot spawn a message bus when setuid"
msgstr "Cannot spawn a message bus when setuid"
-#: gio/gdbusaddress.c:1101
+#: gio/gdbusaddress.c:1108
msgid "Cannot spawn a message bus without a machine-id: "
msgstr "Cannot spawn a message bus without a machine-id: "
-#: gio/gdbusaddress.c:1108
+#: gio/gdbusaddress.c:1115
#, c-format
msgid "Cannot autolaunch D-Bus without X11 $DISPLAY"
msgstr "Cannot autolaunch D-Bus without X11 $DISPLAY"
-#: gio/gdbusaddress.c:1150
+#: gio/gdbusaddress.c:1157
#, c-format
msgid "Error spawning command line “%s”: "
msgstr "Error spawning command line “%s”: "
-#: gio/gdbusaddress.c:1219
+#: gio/gdbusaddress.c:1226
#, c-format
msgid "Cannot determine session bus address (not implemented for this OS)"
msgstr "Cannot determine session bus address (not implemented for this OS)"
-#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192
+#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7241
#, c-format
msgid ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -518,7 +519,7 @@ msgstr ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
"— unknown value “%s”"
-#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201
+#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7250
msgid ""
"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
"variable is not set"
@@ -526,7 +527,7 @@ msgstr ""
"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
"variable is not set"
-#: gio/gdbusaddress.c:1376
+#: gio/gdbusaddress.c:1416
#, c-format
msgid "Unknown bus type %d"
msgstr "Unknown bus type %d"
@@ -546,199 +547,213 @@ msgid ""
msgstr ""
"Exhausted all available authentication mechanisms (tried: %s) (available: %s)"
-#: gio/gdbusauth.c:1167
+#: gio/gdbusauth.c:1170
+msgid "User IDs must be the same for peer and server"
+msgstr "User IDs must be the same for peer and server"
+
+#: gio/gdbusauth.c:1182
msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
msgstr "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
-#: gio/gdbusauthmechanismsha1.c:265
+#: gio/gdbusauthmechanismsha1.c:298
#, c-format
msgid "Error when getting information for directory “%s”: %s"
msgstr "Error when getting information for directory “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:280
+#: gio/gdbusauthmechanismsha1.c:313
#, c-format
msgid ""
"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
msgstr ""
"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
-#: gio/gdbusauthmechanismsha1.c:310
+#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357
#, c-format
msgid "Error creating directory “%s”: %s"
msgstr "Error creating directory “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:355
+#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300
+#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789
+#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049
+#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572
+#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255
+#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243
+#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453
+msgid "Operation not supported"
+msgstr "Operation not supported"
+
+#: gio/gdbusauthmechanismsha1.c:402
#, c-format
msgid "Error opening keyring “%s” for reading: "
msgstr "Error opening keyring “%s” for reading: "
-#: gio/gdbusauthmechanismsha1.c:378 gio/gdbusauthmechanismsha1.c:700
+#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747
#, c-format
msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "Line %d of the keyring at “%s” with content “%s” is malformed"
-#: gio/gdbusauthmechanismsha1.c:392 gio/gdbusauthmechanismsha1.c:714
+#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761
#, c-format
msgid ""
"First token of line %d of the keyring at “%s” with content “%s” is malformed"
msgstr ""
"First token of line %d of the keyring at “%s” with content “%s” is malformed"
-#: gio/gdbusauthmechanismsha1.c:406 gio/gdbusauthmechanismsha1.c:728
+#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775
#, c-format
msgid ""
"Second token of line %d of the keyring at “%s” with content “%s” is malformed"
msgstr ""
"Second token of line %d of the keyring at “%s” with content “%s” is malformed"
-#: gio/gdbusauthmechanismsha1.c:430
+#: gio/gdbusauthmechanismsha1.c:477
#, c-format
msgid "Didn’t find cookie with id %d in the keyring at “%s”"
msgstr "Didn’t find cookie with id %d in the keyring at “%s”"
-#: gio/gdbusauthmechanismsha1.c:476
+#: gio/gdbusauthmechanismsha1.c:523
#, c-format
msgid "Error creating lock file “%s”: %s"
msgstr "Error creating lock file “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:540
+#: gio/gdbusauthmechanismsha1.c:587
#, c-format
msgid "Error deleting stale lock file “%s”: %s"
msgstr "Error deleting stale lock file “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:579
+#: gio/gdbusauthmechanismsha1.c:626
#, c-format
msgid "Error closing (unlinked) lock file “%s”: %s"
msgstr "Error closing (unlinked) lock file “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:590
+#: gio/gdbusauthmechanismsha1.c:637
#, c-format
msgid "Error unlinking lock file “%s”: %s"
msgstr "Error unlinking lock file “%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:667
+#: gio/gdbusauthmechanismsha1.c:714
#, c-format
msgid "Error opening keyring “%s” for writing: "
msgstr "Error opening keyring “%s” for writing: "
-#: gio/gdbusauthmechanismsha1.c:865
+#: gio/gdbusauthmechanismsha1.c:908
#, c-format
msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
msgstr "(Additionally, releasing the lock for “%s” also failed: %s) "
-#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391
+#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2405
msgid "The connection is closed"
msgstr "The connection is closed"
-#: gio/gdbusconnection.c:1892
+#: gio/gdbusconnection.c:1902
msgid "Timeout was reached"
msgstr "Timeout was reached"
-#: gio/gdbusconnection.c:2513
+#: gio/gdbusconnection.c:2528
msgid ""
"Unsupported flags encountered when constructing a client-side connection"
msgstr ""
"Unsupported flags encountered when constructing a client-side connection"
-#: gio/gdbusconnection.c:4163 gio/gdbusconnection.c:4510
+#: gio/gdbusconnection.c:4186 gio/gdbusconnection.c:4533
#, c-format
msgid ""
"No such interface “org.freedesktop.DBus.Properties” on object at path %s"
msgstr ""
"No such interface “org.freedesktop.DBus.Properties” on object at path %s"
-#: gio/gdbusconnection.c:4305
+#: gio/gdbusconnection.c:4328
#, c-format
msgid "No such property “%s”"
msgstr "No such property “%s”"
-#: gio/gdbusconnection.c:4317
+#: gio/gdbusconnection.c:4340
#, c-format
msgid "Property “%s” is not readable"
msgstr "Property “%s” is not readable"
-#: gio/gdbusconnection.c:4328
+#: gio/gdbusconnection.c:4351
#, c-format
msgid "Property “%s” is not writable"
msgstr "Property “%s” is not writable"
-#: gio/gdbusconnection.c:4348
+#: gio/gdbusconnection.c:4371
#, c-format
msgid "Error setting property “%s”: Expected type “%s” but got “%s”"
msgstr "Error setting property “%s”: Expected type “%s” but got “%s”"
-#: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661
-#: gio/gdbusconnection.c:6632
+#: gio/gdbusconnection.c:4476 gio/gdbusconnection.c:4684
+#: gio/gdbusconnection.c:6681
#, c-format
msgid "No such interface “%s”"
msgstr "No such interface “%s”"
-#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141
+#: gio/gdbusconnection.c:4902 gio/gdbusconnection.c:7190
#, c-format
msgid "No such interface “%s” on object at path %s"
msgstr "No such interface “%s” on object at path %s"
-#: gio/gdbusconnection.c:4977
+#: gio/gdbusconnection.c:5000
#, c-format
msgid "No such method “%s”"
msgstr "No such method “%s”"
-#: gio/gdbusconnection.c:5008
+#: gio/gdbusconnection.c:5031
#, c-format
msgid "Type of message, “%s”, does not match expected type “%s”"
msgstr "Type of message, “%s”, does not match expected type “%s”"
-#: gio/gdbusconnection.c:5206
+#: gio/gdbusconnection.c:5229
#, c-format
msgid "An object is already exported for the interface %s at %s"
msgstr "An object is already exported for the interface %s at %s"
-#: gio/gdbusconnection.c:5432
+#: gio/gdbusconnection.c:5455
#, c-format
msgid "Unable to retrieve property %s.%s"
msgstr "Unable to retrieve property %s.%s"
-#: gio/gdbusconnection.c:5488
+#: gio/gdbusconnection.c:5511
#, c-format
msgid "Unable to set property %s.%s"
msgstr "Unable to set property %s.%s"
-#: gio/gdbusconnection.c:5666
+#: gio/gdbusconnection.c:5690
#, c-format
msgid "Method “%s” returned type “%s”, but expected “%s”"
msgstr "Method “%s” returned type “%s”, but expected “%s”"
-#: gio/gdbusconnection.c:6743
+#: gio/gdbusconnection.c:6792
#, c-format
msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
msgstr "Method “%s” on interface “%s” with signature “%s” does not exist"
-#: gio/gdbusconnection.c:6864
+#: gio/gdbusconnection.c:6913
#, c-format
msgid "A subtree is already exported for %s"
msgstr "A subtree is already exported for %s"
-#: gio/gdbusmessage.c:1255
+#: gio/gdbusmessage.c:1266
msgid "type is INVALID"
msgstr "type is INVALID"
-#: gio/gdbusmessage.c:1266
+#: gio/gdbusmessage.c:1277
msgid "METHOD_CALL message: PATH or MEMBER header field is missing"
msgstr "METHOD_CALL message: PATH or MEMBER header field is missing"
-#: gio/gdbusmessage.c:1277
+#: gio/gdbusmessage.c:1288
msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing"
msgstr "METHOD_RETURN message: REPLY_SERIAL header field is missing"
-#: gio/gdbusmessage.c:1289
+#: gio/gdbusmessage.c:1300
msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
msgstr "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
-#: gio/gdbusmessage.c:1302
+#: gio/gdbusmessage.c:1313
msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
msgstr "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
-#: gio/gdbusmessage.c:1310
+#: gio/gdbusmessage.c:1321
msgid ""
"SIGNAL message: The PATH header field is using the reserved value /org/"
"freedesktop/DBus/Local"
@@ -746,7 +761,7 @@ msgstr ""
"SIGNAL message: The PATH header field is using the reserved value /org/"
"freedesktop/DBus/Local"
-#: gio/gdbusmessage.c:1318
+#: gio/gdbusmessage.c:1329
msgid ""
"SIGNAL message: The INTERFACE header field is using the reserved value org."
"freedesktop.DBus.Local"
@@ -754,19 +769,21 @@ msgstr ""
"SIGNAL message: The INTERFACE header field is using the reserved value org."
"freedesktop.DBus.Local"
-#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426
+#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437
#, c-format
msgid "Wanted to read %lu byte but only got %lu"
msgid_plural "Wanted to read %lu bytes but only got %lu"
-msgstr[0] "Wanted to read %lu byte but only got %lu"
-msgstr[1] "Wanted to read %lu bytes but only got %lu"
+msgstr[0] "‫Wanted to read %lu byte but only got %lu"
+msgstr[1] "‫Wanted to read %lu bytes but only got %lu"
+msgstr[2] "‫Wanted to read %lu bytes but only got %lu"
+msgstr[3] "‫Wanted to read %lu bytes but only got %lu"
-#: gio/gdbusmessage.c:1380
+#: gio/gdbusmessage.c:1391
#, c-format
msgid "Expected NUL byte after the string “%s” but found byte %d"
msgstr "Expected NUL byte after the string “%s” but found byte %d"
-#: gio/gdbusmessage.c:1399
+#: gio/gdbusmessage.c:1410
#, c-format
msgid ""
"Expected valid UTF-8 string but found invalid bytes at byte offset %d "
@@ -775,21 +792,21 @@ msgstr ""
"Expected valid UTF-8 string but found invalid bytes at byte offset %d "
"(length of string is %d). The valid UTF-8 string up until that point was “%s”"
-#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900
+#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911
msgid "Value nested too deeply"
msgstr "Value nested too deeply"
-#: gio/gdbusmessage.c:1609
+#: gio/gdbusmessage.c:1620
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus object path"
msgstr "Parsed value “%s” is not a valid D-Bus object path"
-#: gio/gdbusmessage.c:1631
+#: gio/gdbusmessage.c:1642
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus signature"
msgstr "Parsed value “%s” is not a valid D-Bus signature"
-#: gio/gdbusmessage.c:1678
+#: gio/gdbusmessage.c:1689
#, c-format
msgid ""
"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
@@ -799,8 +816,12 @@ msgstr[0] ""
"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
msgstr[1] ""
"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."
+msgstr[2] ""
+"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."
+msgstr[3] ""
+"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."
-#: gio/gdbusmessage.c:1698
+#: gio/gdbusmessage.c:1709
#, c-format
msgid ""
"Encountered array of type “a%c”, expected to have a length a multiple of %u "
@@ -809,19 +830,19 @@ msgstr ""
"Encountered array of type “a%c”, expected to have a length a multiple of %u "
"bytes, but found to be %u bytes in length"
-#: gio/gdbusmessage.c:1884
+#: gio/gdbusmessage.c:1895
#, c-format
msgid "Parsed value “%s” for variant is not a valid D-Bus signature"
msgstr "Parsed value “%s” for variant is not a valid D-Bus signature"
-#: gio/gdbusmessage.c:1925
+#: gio/gdbusmessage.c:1936
#, c-format
msgid ""
"Error deserializing GVariant with type string “%s” from the D-Bus wire format"
msgstr ""
"Error deserializing GVariant with type string “%s” from the D-Bus wire format"
-#: gio/gdbusmessage.c:2110
+#: gio/gdbusmessage.c:2121
#, c-format
msgid ""
"Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
@@ -830,60 +851,62 @@ msgstr ""
"Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
"0x%02x"
-#: gio/gdbusmessage.c:2123
+#: gio/gdbusmessage.c:2134
#, c-format
msgid "Invalid major protocol version. Expected 1 but found %d"
msgstr "Invalid major protocol version. Expected 1 but found %d"
-#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773
+#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784
msgid "Signature header found but is not of type signature"
msgstr "Signature header found but is not of type signature"
-#: gio/gdbusmessage.c:2189
+#: gio/gdbusmessage.c:2200
#, c-format
msgid "Signature header with signature “%s” found but message body is empty"
msgstr "Signature header with signature “%s” found but message body is empty"
-#: gio/gdbusmessage.c:2204
+#: gio/gdbusmessage.c:2215
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus signature (for body)"
msgstr "Parsed value “%s” is not a valid D-Bus signature (for body)"
-#: gio/gdbusmessage.c:2236
+#: gio/gdbusmessage.c:2247
#, c-format
msgid "No signature header in message but the message body is %u byte"
msgid_plural "No signature header in message but the message body is %u bytes"
-msgstr[0] "No signature header in message but the message body is %u byte"
-msgstr[1] "No signature header in message but the message body is %u bytes"
+msgstr[0] "‫No signature header in message but the message body is %u byte"
+msgstr[1] "‫No signature header in message but the message body is %u bytes"
+msgstr[2] "‫No signature header in message but the message body is %u byte"
+msgstr[3] "‫No signature header in message but the message body is %u byte"
-#: gio/gdbusmessage.c:2246
+#: gio/gdbusmessage.c:2257
msgid "Cannot deserialize message: "
msgstr "Cannot deserialize message: "
-#: gio/gdbusmessage.c:2590
+#: gio/gdbusmessage.c:2601
#, c-format
msgid ""
"Error serializing GVariant with type string “%s” to the D-Bus wire format"
msgstr ""
"Error serializing GVariant with type string “%s” to the D-Bus wire format"
-#: gio/gdbusmessage.c:2727
+#: gio/gdbusmessage.c:2738
#, c-format
msgid ""
"Number of file descriptors in message (%d) differs from header field (%d)"
msgstr ""
"Number of file descriptors in message (%d) differs from header field (%d)"
-#: gio/gdbusmessage.c:2735
+#: gio/gdbusmessage.c:2746
msgid "Cannot serialize message: "
msgstr "Cannot serialize message: "
-#: gio/gdbusmessage.c:2788
+#: gio/gdbusmessage.c:2799
#, c-format
msgid "Message body has signature “%s” but there is no signature header"
msgstr "Message body has signature “%s” but there is no signature header"
-#: gio/gdbusmessage.c:2798
+#: gio/gdbusmessage.c:2809
#, c-format
msgid ""
"Message body has type signature “%s” but signature in the header field is "
@@ -892,38 +915,41 @@ msgstr ""
"Message body has type signature “%s” but signature in the header field is "
"“%s”"
-#: gio/gdbusmessage.c:2814
+#: gio/gdbusmessage.c:2825
#, c-format
msgid "Message body is empty but signature in the header field is “(%s)”"
msgstr "Message body is empty but signature in the header field is “(%s)”"
-#: gio/gdbusmessage.c:3367
+#: gio/gdbusmessage.c:3378
#, c-format
msgid "Error return with body of type “%s”"
msgstr "Error return with body of type “%s”"
-#: gio/gdbusmessage.c:3375
+#: gio/gdbusmessage.c:3386
msgid "Error return with empty body"
msgstr "Error return with empty body"
-#: gio/gdbusprivate.c:2244
+#: gio/gdbusprivate.c:2246
#, c-format
msgid "(Type any character to close this window)\n"
msgstr "(Type any character to close this window)\n"
-#: gio/gdbusprivate.c:2418
+#: gio/gdbusprivate.c:2420
#, c-format
msgid "Session dbus not running, and autolaunch failed"
msgstr "Session dbus not running, and autolaunch failed"
-#: gio/gdbusprivate.c:2441
+#: gio/gdbusprivate.c:2443
#, c-format
msgid "Unable to get Hardware profile: %s"
msgstr "Unable to get Hardware profile: %s"
-#: gio/gdbusprivate.c:2486
-msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
-msgstr "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
+#. Translators: Both placeholders are file paths
+#: gio/gdbusprivate.c:2494
+#, c-format
+#| msgid "Unable to trash file %s: %s"
+msgid "Unable to load %s or %s: "
+msgstr "Unable to load %s or %s: "
#: gio/gdbusproxy.c:1562
#, c-format
@@ -944,30 +970,30 @@ msgstr ""
"Cannot invoke method; proxy is for the well-known name %s without an owner, "
"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"
-#: gio/gdbusserver.c:755
+#: gio/gdbusserver.c:763
msgid "Abstract namespace not supported"
msgstr "Abstract namespace not supported"
-#: gio/gdbusserver.c:848
+#: gio/gdbusserver.c:856
msgid "Cannot specify nonce file when creating a server"
msgstr "Cannot specify nonce file when creating a server"
-#: gio/gdbusserver.c:930
+#: gio/gdbusserver.c:938
#, c-format
msgid "Error writing nonce file at “%s”: %s"
msgstr "Error writing nonce file at “%s”: %s"
-#: gio/gdbusserver.c:1103
+#: gio/gdbusserver.c:1113
#, c-format
msgid "The string “%s” is not a valid D-Bus GUID"
msgstr "The string “%s” is not a valid D-Bus GUID"
-#: gio/gdbusserver.c:1143
+#: gio/gdbusserver.c:1153
#, c-format
msgid "Cannot listen on unsupported transport “%s”"
msgstr "Cannot listen on unsupported transport “%s”"
-#: gio/gdbus-tool.c:107
+#: gio/gdbus-tool.c:111
#, c-format
msgid ""
"Commands:\n"
@@ -990,61 +1016,67 @@ msgstr ""
"\n"
"Use “%s COMMAND --help” to get help on each command.\n"
-#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336
-#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187
-#: gio/gdbus-tool.c:1672
+#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345
+#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236
+#: gio/gdbus-tool.c:1724
#, c-format
msgid "Error: %s\n"
msgstr "Error: %s\n"
-#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688
+#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740
#, c-format
msgid "Error parsing introspection XML: %s\n"
msgstr "Error parsing introspection XML: %s\n"
-#: gio/gdbus-tool.c:246
+#: gio/gdbus-tool.c:250
#, c-format
msgid "Error: %s is not a valid name\n"
msgstr "Error: %s is not a valid name\n"
-#: gio/gdbus-tool.c:394
+#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060
+#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130
+#, c-format
+msgid "Error: %s is not a valid object path\n"
+msgstr "Error: %s is not a valid object path\n"
+
+#: gio/gdbus-tool.c:403
msgid "Connect to the system bus"
msgstr "Connect to the system bus"
-#: gio/gdbus-tool.c:395
+#: gio/gdbus-tool.c:404
msgid "Connect to the session bus"
msgstr "Connect to the session bus"
-#: gio/gdbus-tool.c:396
+#: gio/gdbus-tool.c:405
msgid "Connect to given D-Bus address"
msgstr "Connect to given D-Bus address"
-#: gio/gdbus-tool.c:406
+#: gio/gdbus-tool.c:415
msgid "Connection Endpoint Options:"
msgstr "Connection Endpoint Options:"
-#: gio/gdbus-tool.c:407
+#: gio/gdbus-tool.c:416
msgid "Options specifying the connection endpoint"
msgstr "Options specifying the connection endpoint"
-#: gio/gdbus-tool.c:430
+#: gio/gdbus-tool.c:439
#, c-format
msgid "No connection endpoint specified"
msgstr "No connection endpoint specified"
-#: gio/gdbus-tool.c:440
+#: gio/gdbus-tool.c:449
#, c-format
msgid "Multiple connection endpoints specified"
msgstr "Multiple connection endpoints specified"
-#: gio/gdbus-tool.c:513
+#: gio/gdbus-tool.c:522
#, c-format
msgid ""
"Warning: According to introspection data, interface “%s” does not exist\n"
msgstr ""
"Warning: According to introspection data, interface “%s” does not exist\n"
-#: gio/gdbus-tool.c:522
+#: gio/gdbus-tool.c:531
#, c-format
msgid ""
"Warning: According to introspection data, method “%s” does not exist on "
@@ -1053,161 +1085,161 @@ msgstr ""
"Warning: According to introspection data, method “%s” does not exist on "
"interface “%s”\n"
-#: gio/gdbus-tool.c:584
+#: gio/gdbus-tool.c:593
msgid "Optional destination for signal (unique name)"
msgstr "Optional destination for signal (unique name)"
-#: gio/gdbus-tool.c:585
+#: gio/gdbus-tool.c:594
msgid "Object path to emit signal on"
msgstr "Object path to emit signal on"
-#: gio/gdbus-tool.c:586
+#: gio/gdbus-tool.c:595
msgid "Signal and interface name"
msgstr "Signal and interface name"
-#: gio/gdbus-tool.c:619
+#: gio/gdbus-tool.c:628
msgid "Emit a signal."
msgstr "Emit a signal."
-#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775
-#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227
+#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827
+#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279
#, c-format
msgid "Error connecting: %s\n"
msgstr "Error connecting: %s\n"
-#: gio/gdbus-tool.c:694
+#: gio/gdbus-tool.c:703
#, c-format
msgid "Error: %s is not a valid unique bus name.\n"
msgstr "Error: %s is not a valid unique bus name.\n"
-#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818
+#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870
msgid "Error: Object path is not specified\n"
msgstr "Error: Object path is not specified\n"
-#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838
-#: gio/gdbus-tool.c:2078
-#, c-format
-msgid "Error: %s is not a valid object path\n"
-msgstr "Error: %s is not a valid object path\n"
-
-#: gio/gdbus-tool.c:756
+#: gio/gdbus-tool.c:765
msgid "Error: Signal name is not specified\n"
msgstr "Error: Signal name is not specified\n"
-#: gio/gdbus-tool.c:770
+#: gio/gdbus-tool.c:779
#, c-format
msgid "Error: Signal name “%s” is invalid\n"
msgstr "Error: Signal name “%s” is invalid\n"
-#: gio/gdbus-tool.c:782
+#: gio/gdbus-tool.c:791
#, c-format
msgid "Error: %s is not a valid interface name\n"
msgstr "Error: %s is not a valid interface name\n"
-#: gio/gdbus-tool.c:788
+#: gio/gdbus-tool.c:797
#, c-format
msgid "Error: %s is not a valid member name\n"
msgstr "Error: %s is not a valid member name\n"
#. Use the original non-"parse-me-harder" error
-#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156
+#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172
#, c-format
msgid "Error parsing parameter %d: %s\n"
msgstr "Error parsing parameter %d: %s\n"
-#: gio/gdbus-tool.c:857
+#: gio/gdbus-tool.c:866
#, c-format
msgid "Error flushing connection: %s\n"
msgstr "Error flushing connection: %s\n"
-#: gio/gdbus-tool.c:884
+#: gio/gdbus-tool.c:893
msgid "Destination name to invoke method on"
msgstr "Destination name to invoke method on"
-#: gio/gdbus-tool.c:885
+#: gio/gdbus-tool.c:894
msgid "Object path to invoke method on"
msgstr "Object path to invoke method on"
-#: gio/gdbus-tool.c:886
+#: gio/gdbus-tool.c:895
msgid "Method and interface name"
msgstr "Method and interface name"
-#: gio/gdbus-tool.c:887
+#: gio/gdbus-tool.c:896
msgid "Timeout in seconds"
msgstr "Timeout in seconds"
-#: gio/gdbus-tool.c:926
+#: gio/gdbus-tool.c:942
msgid "Invoke a method on a remote object."
msgstr "Invoke a method on a remote object."
-#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032
+#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084
msgid "Error: Destination is not specified\n"
msgstr "Error: Destination is not specified\n"
-#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043
+#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095
#, c-format
msgid "Error: %s is not a valid bus name\n"
msgstr "Error: %s is not a valid bus name\n"
-#: gio/gdbus-tool.c:1059
+#: gio/gdbus-tool.c:1075
msgid "Error: Method name is not specified\n"
msgstr "Error: Method name is not specified\n"
-#: gio/gdbus-tool.c:1070
+#: gio/gdbus-tool.c:1086
#, c-format
msgid "Error: Method name “%s” is invalid\n"
msgstr "Error: Method name “%s” is invalid\n"
-#: gio/gdbus-tool.c:1148
+#: gio/gdbus-tool.c:1164
#, c-format
msgid "Error parsing parameter %d of type “%s”: %s\n"
msgstr "Error parsing parameter %d of type “%s”: %s\n"
-#: gio/gdbus-tool.c:1634
+#: gio/gdbus-tool.c:1190
+#, c-format
+#| msgid "Error reading from handle: %s"
+msgid "Error adding handle %d: %s\n"
+msgstr "Error adding handle %d: %s\n"
+
+#: gio/gdbus-tool.c:1686
msgid "Destination name to introspect"
msgstr "Destination name to introspect"
-#: gio/gdbus-tool.c:1635
+#: gio/gdbus-tool.c:1687
msgid "Object path to introspect"
msgstr "Object path to introspect"
-#: gio/gdbus-tool.c:1636
+#: gio/gdbus-tool.c:1688
msgid "Print XML"
msgstr "Print XML"
-#: gio/gdbus-tool.c:1637
+#: gio/gdbus-tool.c:1689
msgid "Introspect children"
msgstr "Introspect children"
-#: gio/gdbus-tool.c:1638
+#: gio/gdbus-tool.c:1690
msgid "Only print properties"
msgstr "Only print properties"
-#: gio/gdbus-tool.c:1727
+#: gio/gdbus-tool.c:1779
msgid "Introspect a remote object."
msgstr "Introspect a remote object."
-#: gio/gdbus-tool.c:1933
+#: gio/gdbus-tool.c:1985
msgid "Destination name to monitor"
msgstr "Destination name to monitor"
-#: gio/gdbus-tool.c:1934
+#: gio/gdbus-tool.c:1986
msgid "Object path to monitor"
msgstr "Object path to monitor"
-#: gio/gdbus-tool.c:1959
+#: gio/gdbus-tool.c:2011
msgid "Monitor a remote object."
-msgstr "corrupted object"
+msgstr "Monitor a remote object."
-#: gio/gdbus-tool.c:2017
+#: gio/gdbus-tool.c:2069
msgid "Error: can’t monitor a non-message-bus connection\n"
msgstr "Error: can’t monitor a non-message-bus connection\n"
-#: gio/gdbus-tool.c:2141
+#: gio/gdbus-tool.c:2193
msgid "Service to activate before waiting for the other one (well-known name)"
msgstr "Service to activate before waiting for the other one (well-known name)"
-#: gio/gdbus-tool.c:2144
+#: gio/gdbus-tool.c:2196
msgid ""
"Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
"(default)"
@@ -1215,63 +1247,63 @@ msgstr ""
"Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
"(default)"
-#: gio/gdbus-tool.c:2192
+#: gio/gdbus-tool.c:2244
msgid "[OPTION…] BUS-NAME"
msgstr "[OPTION…] BUS-NAME"
-#: gio/gdbus-tool.c:2193
+#: gio/gdbus-tool.c:2245
msgid "Wait for a bus name to appear."
msgstr "Wait for a bus name to appear."
-#: gio/gdbus-tool.c:2269
+#: gio/gdbus-tool.c:2321
msgid "Error: A service to activate for must be specified.\n"
msgstr "Error: A service to activate for must be specified.\n"
-#: gio/gdbus-tool.c:2274
+#: gio/gdbus-tool.c:2326
msgid "Error: A service to wait for must be specified.\n"
msgstr "Error: A service to wait for must be specified.\n"
-#: gio/gdbus-tool.c:2279
+#: gio/gdbus-tool.c:2331
msgid "Error: Too many arguments.\n"
msgstr "Error: Too many arguments.\n"
-#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294
+#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346
#, c-format
msgid "Error: %s is not a valid well-known bus name.\n"
msgstr "Error: %s is not a valid well-known bus name.\n"
-#: gio/gdesktopappinfo.c:2073 gio/gdesktopappinfo.c:4893
+#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932
msgid "Unnamed"
msgstr "Unnamed"
-#: gio/gdesktopappinfo.c:2483
+#: gio/gdesktopappinfo.c:2516
msgid "Desktop file didn’t specify Exec field"
msgstr "Desktop file didn’t specify Exec field"
-#: gio/gdesktopappinfo.c:2763
+#: gio/gdesktopappinfo.c:2801
msgid "Unable to find terminal required for application"
msgstr "Unable to find terminal required for application"
-#: gio/gdesktopappinfo.c:3414
+#: gio/gdesktopappinfo.c:3452
#, c-format
msgid "Can’t create user application configuration folder %s: %s"
msgstr "Can’t create user application configuration folder %s: %s"
-#: gio/gdesktopappinfo.c:3418
+#: gio/gdesktopappinfo.c:3456
#, c-format
msgid "Can’t create user MIME configuration folder %s: %s"
msgstr "Can’t create user MIME configuration folder %s: %s"
-#: gio/gdesktopappinfo.c:3660 gio/gdesktopappinfo.c:3684
+#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722
msgid "Application information lacks an identifier"
msgstr "Application information lacks an identifier"
-#: gio/gdesktopappinfo.c:3920
+#: gio/gdesktopappinfo.c:3958
#, c-format
msgid "Can’t create user desktop file %s"
msgstr "Can’t create user desktop file %s"
-#: gio/gdesktopappinfo.c:4056
+#: gio/gdesktopappinfo.c:4094
#, c-format
msgid "Custom definition for %s"
msgstr "Custom definition for %s"
@@ -1336,87 +1368,77 @@ msgstr "Malformed number of tokens (%d) in GEmblemedIcon encoding"
msgid "Expected a GEmblem for GEmblemedIcon"
msgstr "Expected a GEmblem for GEmblemedIcon"
-#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658
-#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912
-#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777
-#: gio/gfile.c:4070 gio/gfile.c:4540 gio/gfile.c:4951 gio/gfile.c:5036
-#: gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 gio/gfile.c:5411
-#: gio/gfile.c:8121 gio/gfile.c:8211 gio/gfile.c:8295
-#: gio/win32/gwinhttpfile.c:437
-msgid "Operation not supported"
-msgstr "Operation not supported"
-
#. Translators: This is an error message when
#. * trying to find the enclosing (user visible)
#. * mount of a file, but none exists.
#.
-#: gio/gfile.c:1543
+#: gio/gfile.c:1561
msgid "Containing mount does not exist"
msgstr "Containing mount does not exist"
-#: gio/gfile.c:2590 gio/glocalfile.c:2430
+#: gio/gfile.c:2608 gio/glocalfile.c:2472
msgid "Can’t copy over directory"
msgstr "Can’t copy over directory"
-#: gio/gfile.c:2650
+#: gio/gfile.c:2668
msgid "Can’t copy directory over directory"
msgstr "Can’t copy directory over directory"
-#: gio/gfile.c:2658
+#: gio/gfile.c:2676
msgid "Target file exists"
msgstr "Target file exists"
-#: gio/gfile.c:2677
+#: gio/gfile.c:2695
msgid "Can’t recursively copy directory"
msgstr "Can’t recursively copy directory"
-#: gio/gfile.c:2952
+#: gio/gfile.c:2996
msgid "Splice not supported"
msgstr "Symbolic links not supported"
-#: gio/gfile.c:2956 gio/gfile.c:3001
+#: gio/gfile.c:3000
#, c-format
msgid "Error splicing file: %s"
msgstr "Error opening file: %s"
-#: gio/gfile.c:3117
+#: gio/gfile.c:3152
msgid "Copy (reflink/clone) between mounts is not supported"
msgstr "Copy (reflink/clone) between mounts is not supported"
-#: gio/gfile.c:3121
+#: gio/gfile.c:3156
msgid "Copy (reflink/clone) is not supported or invalid"
msgstr "Copy (reflink/clone) is not supported or invalid"
-#: gio/gfile.c:3126
+#: gio/gfile.c:3161
msgid "Copy (reflink/clone) is not supported or didn’t work"
msgstr "Copy (reflink/clone) is not supported or didn’t work"
-#: gio/gfile.c:3190
+#: gio/gfile.c:3226
msgid "Can’t copy special file"
msgstr "Can’t copy special file"
-#: gio/gfile.c:4003
+#: gio/gfile.c:4035
msgid "Invalid symlink value given"
msgstr "Invalid symlink value given"
-#: gio/gfile.c:4013 glib/gfileutils.c:2349
+#: gio/gfile.c:4045 glib/gfileutils.c:2354
msgid "Symbolic links not supported"
msgstr "Symbolic links not supported"
-#: gio/gfile.c:4181
+#: gio/gfile.c:4213
msgid "Trash not supported"
msgstr "Trash not supported"
-#: gio/gfile.c:4293
+#: gio/gfile.c:4325
#, c-format
msgid "File names cannot contain “%c”"
msgstr "File names cannot contain “%c”"
-#: gio/gfile.c:6774 gio/gvolume.c:364
+#: gio/gfile.c:6806 gio/gvolume.c:364
msgid "volume doesn’t implement mount"
msgstr "volume doesn’t implement mount"
-#: gio/gfile.c:6888 gio/gfile.c:6936
+#: gio/gfile.c:6920 gio/gfile.c:6968
msgid "No application is registered as handling this file"
msgstr "No application is registered as handling this file"
@@ -1433,12 +1455,12 @@ msgstr "File enumerator has outstanding operation"
msgid "File enumerator is already closed"
msgstr "File enumerator is already closed"
-#: gio/gfileicon.c:236
+#: gio/gfileicon.c:250
#, c-format
msgid "Can’t handle version %d of GFileIcon encoding"
msgstr "Can’t handle version %d of GFileIcon encoding"
-#: gio/gfileicon.c:246
+#: gio/gfileicon.c:260
msgid "Malformed input data for GFileIcon"
msgstr "Malformed input data for GFileIcon"
@@ -1487,7 +1509,12 @@ msgstr "HTTP proxy authentication required"
msgid "HTTP proxy connection failed: %i"
msgstr "HTTP proxy connection failed: %i"
-#: gio/ghttpproxy.c:269
+#: gio/ghttpproxy.c:266
+#| msgid "HTTP proxy connection failed: %i"
+msgid "HTTP proxy response too big"
+msgstr "HTTP proxy response too big"
+
+#: gio/ghttpproxy.c:283
msgid "HTTP proxy server closed connection unexpectedly."
msgstr "HTTP proxy server closed connection unexpectedly."
@@ -1562,7 +1589,7 @@ msgstr "Input stream doesn’t implement read"
#. Translators: This is an error you get if there is
#. * already an operation running against this stream when
#. * you try to start one
-#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208
+#: gio/ginputstream.c:1247 gio/giostream.c:310 gio/goutputstream.c:2208
msgid "Stream has outstanding operation"
msgstr "Stream has outstanding operation"
@@ -1603,58 +1630,63 @@ msgid "Show information about locations"
msgstr "Show information about locations"
#: gio/gio-tool.c:232
+#| msgid "List static actions for an application (from .desktop file)"
+msgid "Launch an application from a desktop file"
+msgstr "Launch an application from a desktop file"
+
+#: gio/gio-tool.c:233
msgid "List the contents of locations"
msgstr "List the contents of locations"
-#: gio/gio-tool.c:233
+#: gio/gio-tool.c:234
msgid "Get or set the handler for a mimetype"
msgstr "Get or set the handler for a mimetype"
-#: gio/gio-tool.c:234
+#: gio/gio-tool.c:235
msgid "Create directories"
msgstr "Create directories"
-#: gio/gio-tool.c:235
+#: gio/gio-tool.c:236
msgid "Monitor files and directories for changes"
msgstr "Monitor files and directories for changes"
-#: gio/gio-tool.c:236
+#: gio/gio-tool.c:237
msgid "Mount or unmount the locations"
msgstr "Mount or unmount the locations"
-#: gio/gio-tool.c:237
+#: gio/gio-tool.c:238
msgid "Move one or more files"
msgstr "Move one or more files"
-#: gio/gio-tool.c:238
+#: gio/gio-tool.c:239
msgid "Open files with the default application"
msgstr "Open files with the default application"
-#: gio/gio-tool.c:239
+#: gio/gio-tool.c:240
msgid "Rename a file"
msgstr "Rename a file"
-#: gio/gio-tool.c:240
+#: gio/gio-tool.c:241
msgid "Delete one or more files"
msgstr "Delete one or more files"
-#: gio/gio-tool.c:241
+#: gio/gio-tool.c:242
msgid "Read from standard input and save"
msgstr "Read from standard input and save"
-#: gio/gio-tool.c:242
+#: gio/gio-tool.c:243
msgid "Set a file attribute"
msgstr "Set a file attribute"
-#: gio/gio-tool.c:243
+#: gio/gio-tool.c:244
msgid "Move files or directories to the trash"
msgstr "Move files or directories to the trash"
-#: gio/gio-tool.c:244
+#: gio/gio-tool.c:245
msgid "Lists the contents of locations in a tree"
msgstr "Lists the contents of locations in a tree"
-#: gio/gio-tool.c:246
+#: gio/gio-tool.c:247
#, c-format
msgid "Use %s to get detailed help.\n"
msgstr "Use %s to get detailed help.\n"
@@ -1664,12 +1696,12 @@ msgid "Error writing to stdout"
msgstr "Error writing to stdout"
#. Translators: commandline placeholder
-#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:333 gio/gio-tool-list.c:172
+#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172
#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39
#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43
-#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
+#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89
-#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239
+#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239
msgid "LOCATION"
msgstr "LOCATION"
@@ -1687,9 +1719,9 @@ msgstr ""
"locations instead of local files: for example, you can use something\n"
"like smb://server/resource/file.txt as location."
-#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76
-#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
-#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136
+#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76
+#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
+#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303
msgid "No locations given"
msgstr "No locations given"
@@ -1824,24 +1856,24 @@ msgstr "uri: %s\n"
msgid "local path: %s\n"
msgstr "local path: %s\n"
-#: gio/gio-tool-info.c:199
+#: gio/gio-tool-info.c:205
#, c-format
msgid "unix mount: %s%s %s %s %s\n"
msgstr "unix mount: %s%s %s %s %s\n"
-#: gio/gio-tool-info.c:279
+#: gio/gio-tool-info.c:286
msgid "Settable attributes:\n"
msgstr "Settable attributes:\n"
-#: gio/gio-tool-info.c:303
+#: gio/gio-tool-info.c:310
msgid "Writable attribute namespaces:\n"
msgstr "Writable attribute namespaces:\n"
-#: gio/gio-tool-info.c:338
+#: gio/gio-tool-info.c:345
msgid "Show information about locations."
msgstr "Show information about locations."
-#: gio/gio-tool-info.c:340
+#: gio/gio-tool-info.c:347
msgid ""
"gio info is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -1855,6 +1887,47 @@ msgstr ""
"be specified with their GIO name, e.g. standard::icon, or just by\n"
"namespace, e.g. unix, or by “*”, which matches all attributes"
+#. Translators: commandline placeholder
+#: gio/gio-tool-launch.c:54
+msgid "DESKTOP-FILE [FILE-ARG …]"
+msgstr "DESKTOP-FILE [FILE-ARG …]"
+
+#: gio/gio-tool-launch.c:57
+msgid ""
+"Launch an application from a desktop file, passing optional filename "
+"arguments to it."
+msgstr ""
+"Launch an application from a desktop file, passing optional filename "
+"arguments to it."
+
+#: gio/gio-tool-launch.c:77
+#| msgid "No files given"
+msgid "No desktop file given"
+msgstr "No desktop file given"
+
+#: gio/gio-tool-launch.c:85
+#| msgid "There is no GCredentials support for your platform"
+msgid "The launch command is not currently supported on this platform"
+msgstr "The launch command is not currently supported on this platform"
+
+#: gio/gio-tool-launch.c:98
+#, c-format
+#| msgid "Unable to trash file %s: %s"
+msgid "Unable to load ‘%s‘: %s"
+msgstr "Unable to load ‘%s‘: %s"
+
+#: gio/gio-tool-launch.c:107
+#, c-format
+#| msgid "Failed to load info for handler “%s”"
+msgid "Unable to load application information for ‘%s‘"
+msgstr "Unable to load application information for ‘%s‘"
+
+#: gio/gio-tool-launch.c:119
+#, c-format
+#| msgid "Default application for “%s”: %s\n"
+msgid "Unable to launch application ‘%s’: %s"
+msgstr "Unable to launch application ‘%s’: %s"
+
#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32
msgid "Show hidden files"
msgstr "Show hidden files"
@@ -1992,7 +2065,7 @@ msgstr "Report moves and renames as simple deleted/created events"
msgid "Watch for mount events"
msgstr "Watch for mount events"
-#: gio/gio-tool-monitor.c:208
+#: gio/gio-tool-monitor.c:209
msgid "Monitor files or directories for changes."
msgstr "Monitor files or directories for changes."
@@ -2116,7 +2189,7 @@ msgstr ""
"Open files with the default application that\n"
"is registered to handle files of this type."
-#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31
+#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33
msgid "Ignore nonexistent files, never prompt"
msgstr "Ignore nonexistent files, never prompt"
@@ -2229,13 +2302,54 @@ msgstr "Value not specified"
msgid "Invalid attribute type “%s”"
msgstr "Invalid attribute type “%s”"
-#: gio/gio-tool-trash.c:32
+#: gio/gio-tool-trash.c:34
msgid "Empty the trash"
msgstr "Empty the trash"
-#: gio/gio-tool-trash.c:86
-msgid "Move files or directories to the trash."
-msgstr "Move files or directories to the trash."
+#: gio/gio-tool-trash.c:35
+#| msgid "List the contents of the locations."
+msgid "List files in the trash with their original locations"
+msgstr "List files in the trash with their original locations"
+
+#: gio/gio-tool-trash.c:36
+msgid ""
+"Restore a file from trash to its original location (possibly recreating the "
+"directory)"
+msgstr ""
+"Restore a file from trash to its original location (possibly recreating the "
+"directory)"
+
+#: gio/gio-tool-trash.c:106
+#| msgid "Unable to find terminal required for application"
+msgid "Unable to find original path"
+msgstr "Unable to find original path"
+
+#: gio/gio-tool-trash.c:123
+#| msgid "Unable to create socket: %s"
+msgid "Unable to recreate original location: "
+msgstr "Unable to recreate original location: "
+
+#: gio/gio-tool-trash.c:136
+#| msgid "unable to find desktop file for application %s\n"
+msgid "Unable to move file to its original location: "
+msgstr "Unable to move file to its original location: "
+
+#: gio/gio-tool-trash.c:225
+#| msgid "Move files or directories to the trash."
+msgid "Move/Restore files or directories to the trash."
+msgstr "Move/Restore files or directories to the trash."
+
+#: gio/gio-tool-trash.c:227
+msgid ""
+"Note: for --restore switch, if the original location of the trashed file \n"
+"already exists, it will not be overwritten unless --force is set."
+msgstr ""
+"Note: for --restore switch, if the original location of the trashed file \n"
+"already exists, it will not be overwritten unless --force is set."
+
+#: gio/gio-tool-trash.c:258
+msgid "Location given doesn't start with trash:///"
+msgstr "Location given doesn't start with trash:///"
#: gio/gio-tool-tree.c:33
msgid "Follow symbolic links, mounts and shortcuts"
@@ -2853,7 +2967,7 @@ msgstr "No schema files found: doing nothing."
msgid "No schema files found: removed existing output file."
msgstr "No schema files found: removed existing output file."
-#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:420
+#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436
#, c-format
msgid "Invalid filename %s"
msgstr "Invalid filename %s"
@@ -2885,8 +2999,8 @@ msgstr "Error renaming file %s: %s"
msgid "Can’t rename file, filename already exists"
msgstr "Can’t rename file, filename already exists"
-#: gio/glocalfile.c:1182 gio/glocalfile.c:2324 gio/glocalfile.c:2352
-#: gio/glocalfile.c:2491 gio/glocalfileoutputstream.c:650
+#: gio/glocalfile.c:1182 gio/glocalfile.c:2366 gio/glocalfile.c:2394
+#: gio/glocalfile.c:2533 gio/glocalfileoutputstream.c:656
msgid "Invalid filename"
msgstr "Invalid filename"
@@ -2900,91 +3014,93 @@ msgstr "Error opening file %s: %s"
msgid "Error removing file %s: %s"
msgstr "Error removing file %s: %s"
-#: gio/glocalfile.c:1969
+#: gio/glocalfile.c:1980 gio/glocalfile.c:1991
#, c-format
msgid "Error trashing file %s: %s"
msgstr "Error trashing file %s: %s"
-#: gio/glocalfile.c:2010
+#: gio/glocalfile.c:2029
#, c-format
-msgid "Unable to create trash dir %s: %s"
-msgstr "Unable to create trash dir %s: %s"
+#| msgid "Unable to create trash dir %s: %s"
+msgid "Unable to create trash directory %s: %s"
+msgstr "Unable to create trash directory %s: %s"
-#: gio/glocalfile.c:2030
+#: gio/glocalfile.c:2050
#, c-format
msgid "Unable to find toplevel directory to trash %s"
msgstr "Unable to find toplevel directory to trash %s"
-#: gio/glocalfile.c:2038
+#: gio/glocalfile.c:2058
#, c-format
msgid "Trashing on system internal mounts is not supported"
msgstr "Trashing on system internal mounts is not supported"
-#: gio/glocalfile.c:2118 gio/glocalfile.c:2138
+#: gio/glocalfile.c:2141 gio/glocalfile.c:2169
#, c-format
-msgid "Unable to find or create trash directory for %s"
-msgstr "Unable to find or create trash directory for %s"
+#| msgid "Unable to find or create trash directory for %s"
+msgid "Unable to find or create trash directory %s to trash %s"
+msgstr "Unable to find or create trash directory %s to trash %s"
-#: gio/glocalfile.c:2173
+#: gio/glocalfile.c:2215
#, c-format
msgid "Unable to create trashing info file for %s: %s"
msgstr "Unable to create trashing info file for %s: %s"
-#: gio/glocalfile.c:2235
+#: gio/glocalfile.c:2277
#, c-format
msgid "Unable to trash file %s across filesystem boundaries"
msgstr "Unable to trash file %s across filesystem boundaries"
-#: gio/glocalfile.c:2239 gio/glocalfile.c:2295
+#: gio/glocalfile.c:2281 gio/glocalfile.c:2337
#, c-format
msgid "Unable to trash file %s: %s"
msgstr "Unable to trash file %s: %s"
-#: gio/glocalfile.c:2301
+#: gio/glocalfile.c:2343
#, c-format
msgid "Unable to trash file %s"
msgstr "Unable to trash file %s"
-#: gio/glocalfile.c:2327
+#: gio/glocalfile.c:2369
#, c-format
msgid "Error creating directory %s: %s"
msgstr "Error creating directory %s: %s"
-#: gio/glocalfile.c:2356
+#: gio/glocalfile.c:2398
#, c-format
msgid "Filesystem does not support symbolic links"
msgstr "Filesystem does not support symbolic links"
-#: gio/glocalfile.c:2359
+#: gio/glocalfile.c:2401
#, c-format
msgid "Error making symbolic link %s: %s"
msgstr "Error making symbolic link %s: %s"
-#: gio/glocalfile.c:2402 gio/glocalfile.c:2437 gio/glocalfile.c:2494
+#: gio/glocalfile.c:2444 gio/glocalfile.c:2479 gio/glocalfile.c:2536
#, c-format
msgid "Error moving file %s: %s"
msgstr "Error moving file %s: %s"
-#: gio/glocalfile.c:2425
+#: gio/glocalfile.c:2467
msgid "Can’t move directory over directory"
msgstr "Can’t move directory over directory"
-#: gio/glocalfile.c:2451 gio/glocalfileoutputstream.c:1039
-#: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068
-#: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099
+#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1079
+#: gio/glocalfileoutputstream.c:1093 gio/glocalfileoutputstream.c:1108
+#: gio/glocalfileoutputstream.c:1125 gio/glocalfileoutputstream.c:1139
msgid "Backup file creation failed"
msgstr "Backup file creation failed"
-#: gio/glocalfile.c:2470
+#: gio/glocalfile.c:2512
#, c-format
msgid "Error removing target file: %s"
msgstr "Error removing target file: %s"
-#: gio/glocalfile.c:2484
+#: gio/glocalfile.c:2526
msgid "Move between mounts not supported"
msgstr "Move between mounts not supported"
-#: gio/glocalfile.c:2658
+#: gio/glocalfile.c:2700
#, c-format
msgid "Could not determine the disk usage of %s: %s"
msgstr "Could not determine the disk usage of %s: %s"
@@ -3006,189 +3122,185 @@ msgstr "Invalid extended attribute name"
msgid "Error setting extended attribute “%s”: %s"
msgstr "Error setting extended attribute “%s”: %s"
-#: gio/glocalfileinfo.c:1663
+#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
msgstr " (invalid encoding)"
-#: gio/glocalfileinfo.c:1822 gio/glocalfileoutputstream.c:915
+#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943
#, c-format
msgid "Error when getting information for file “%s”: %s"
msgstr "Error when getting information for file “%s”: %s"
-#: gio/glocalfileinfo.c:2088
+#: gio/glocalfileinfo.c:2134
#, c-format
msgid "Error when getting information for file descriptor: %s"
msgstr "Error when getting information for file descriptor: %s"
-#: gio/glocalfileinfo.c:2133
+#: gio/glocalfileinfo.c:2179
msgid "Invalid attribute type (uint32 expected)"
msgstr "Invalid attribute type (uint32 expected)"
-#: gio/glocalfileinfo.c:2151
+#: gio/glocalfileinfo.c:2197
msgid "Invalid attribute type (uint64 expected)"
msgstr "Invalid attribute type (uint64 expected)"
-#: gio/glocalfileinfo.c:2170 gio/glocalfileinfo.c:2189
+#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235
msgid "Invalid attribute type (byte string expected)"
msgstr "Invalid attribute type (byte string expected)"
-#: gio/glocalfileinfo.c:2236
+#: gio/glocalfileinfo.c:2282
msgid "Cannot set permissions on symlinks"
msgstr "Cannot set permissions on symlinks"
-#: gio/glocalfileinfo.c:2252
+#: gio/glocalfileinfo.c:2298
#, c-format
msgid "Error setting permissions: %s"
msgstr "Error setting permissions: %s"
-#: gio/glocalfileinfo.c:2303
+#: gio/glocalfileinfo.c:2349
#, c-format
msgid "Error setting owner: %s"
msgstr "Error setting owner: %s"
-#: gio/glocalfileinfo.c:2326
+#: gio/glocalfileinfo.c:2372
msgid "symlink must be non-NULL"
msgstr "symlink must be non-NULL"
-#: gio/glocalfileinfo.c:2336 gio/glocalfileinfo.c:2355
-#: gio/glocalfileinfo.c:2366
+#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401
+#: gio/glocalfileinfo.c:2412
#, c-format
msgid "Error setting symlink: %s"
msgstr "Error setting symlink: %s"
-#: gio/glocalfileinfo.c:2345
+#: gio/glocalfileinfo.c:2391
msgid "Error setting symlink: file is not a symlink"
msgstr "Error setting symlink: file is not a symlink"
-#: gio/glocalfileinfo.c:2417
+#: gio/glocalfileinfo.c:2463
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
msgstr "Extra nanoseconds %d for UNIX timestamp %lld are negative"
-#: gio/glocalfileinfo.c:2426
+#: gio/glocalfileinfo.c:2472
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
msgstr "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
-#: gio/glocalfileinfo.c:2436
+#: gio/glocalfileinfo.c:2482
#, c-format
msgid "UNIX timestamp %lld does not fit into 64 bits"
msgstr "UNIX timestamp %lld does not fit into 64 bits"
-#: gio/glocalfileinfo.c:2447
+#: gio/glocalfileinfo.c:2493
#, c-format
msgid "UNIX timestamp %lld is outside of the range supported by Windows"
msgstr "UNIX timestamp %lld is outside of the range supported by Windows"
-#: gio/glocalfileinfo.c:2511
+#: gio/glocalfileinfo.c:2557
#, c-format
-#| msgid "Value “%s” cannot be interpreted as a number."
msgid "File name “%s” cannot be converted to UTF-16"
msgstr "File name “%s” cannot be converted to UTF-16"
-#: gio/glocalfileinfo.c:2530
+#: gio/glocalfileinfo.c:2576
#, c-format
-#| msgid "Value “%s” cannot be interpreted as a number."
msgid "File “%s” cannot be opened: Windows Error %lu"
msgstr "File “%s” cannot be opened: Windows Error %lu"
-#: gio/glocalfileinfo.c:2543
+#: gio/glocalfileinfo.c:2589
#, c-format
-#| msgid "Error setting modification or access time: %s"
msgid "Error setting modification or access time for file “%s”: %lu"
msgstr "Error setting modification or access time for file “%s”: %lu"
-#: gio/glocalfileinfo.c:2644
+#: gio/glocalfileinfo.c:2690
#, c-format
msgid "Error setting modification or access time: %s"
msgstr "Error setting modification or access time: %s"
# c-format
-#: gio/glocalfileinfo.c:2667
+#: gio/glocalfileinfo.c:2713
msgid "SELinux context must be non-NULL"
msgstr "SELinux context must be non-NULL"
-#: gio/glocalfileinfo.c:2682
+#: gio/glocalfileinfo.c:2720
+msgid "SELinux is not enabled on this system"
+msgstr "SELinux is not enabled on this system"
+
+#: gio/glocalfileinfo.c:2730
#, c-format
msgid "Error setting SELinux context: %s"
msgstr "Error setting SELinux context: %s"
-#: gio/glocalfileinfo.c:2689
-msgid "SELinux is not enabled on this system"
-msgstr "SELinux is not enabled on this system"
-
-#: gio/glocalfileinfo.c:2781
+#: gio/glocalfileinfo.c:2823
#, c-format
msgid "Setting attribute %s not supported"
msgstr "Setting attribute %s not supported"
-#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:795
+#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801
#, c-format
msgid "Error reading from file: %s"
msgstr "Error reading from file: %s"
-#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211
-#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333
-#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:1117
-#, c-format
-msgid "Error seeking in file: %s"
-msgstr "Error seeking in file: %s"
-
-#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:347
-#: gio/glocalfileoutputstream.c:441
+#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353
+#: gio/glocalfileoutputstream.c:447
#, c-format
msgid "Error closing file: %s"
msgstr "Error closing file: %s"
-#: gio/glocalfilemonitor.c:865
+#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563
+#: gio/glocalfileoutputstream.c:1157
+#, c-format
+msgid "Error seeking in file: %s"
+msgstr "Error seeking in file: %s"
+
+#: gio/glocalfilemonitor.c:866
msgid "Unable to find default local file monitor type"
msgstr "Unable to find default local file monitor type"
-#: gio/glocalfileoutputstream.c:214 gio/glocalfileoutputstream.c:292
-#: gio/glocalfileoutputstream.c:328 gio/glocalfileoutputstream.c:816
+#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298
+#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822
#, c-format
msgid "Error writing to file: %s"
msgstr "Error writing to file: %s"
-#: gio/glocalfileoutputstream.c:374
+#: gio/glocalfileoutputstream.c:380
#, c-format
msgid "Error removing old backup link: %s"
msgstr "Error removing old backup link: %s"
-#: gio/glocalfileoutputstream.c:388 gio/glocalfileoutputstream.c:401
+#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407
#, c-format
msgid "Error creating backup copy: %s"
msgstr "Error creating backup copy: %s"
-#: gio/glocalfileoutputstream.c:419
+#: gio/glocalfileoutputstream.c:425
#, c-format
msgid "Error renaming temporary file: %s"
msgstr "Error renaming temporary file: %s"
-#: gio/glocalfileoutputstream.c:603 gio/glocalfileoutputstream.c:1168
+#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1208
#, c-format
msgid "Error truncating file: %s"
msgstr "Error truncating file: %s"
-#: gio/glocalfileoutputstream.c:656 gio/glocalfileoutputstream.c:894
-#: gio/glocalfileoutputstream.c:1149 gio/gsubprocess.c:380
+#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907
+#: gio/glocalfileoutputstream.c:1189 gio/gsubprocess.c:226
#, c-format
msgid "Error opening file “%s”: %s"
msgstr "Error opening file “%s”: %s"
-#: gio/glocalfileoutputstream.c:928
+#: gio/glocalfileoutputstream.c:957
msgid "Target file is a directory"
msgstr "Target file is a directory"
-#: gio/glocalfileoutputstream.c:933
+#: gio/glocalfileoutputstream.c:971
msgid "Target file is not a regular file"
msgstr "Target file is not a regular file"
-#: gio/glocalfileoutputstream.c:945
+#: gio/glocalfileoutputstream.c:984
msgid "The file was externally modified"
msgstr "The file was externally modified"
-#: gio/glocalfileoutputstream.c:1133
+#: gio/glocalfileoutputstream.c:1173
#, c-format
msgid "Error removing old file: %s"
msgstr "Error removing old file: %s"
@@ -3343,15 +3455,15 @@ msgstr "%s not implemented"
msgid "Invalid domain"
msgstr "Invalid domain"
-#: gio/gresource.c:672 gio/gresource.c:931 gio/gresource.c:970
-#: gio/gresource.c:1094 gio/gresource.c:1166 gio/gresource.c:1239
-#: gio/gresource.c:1320 gio/gresourcefile.c:476 gio/gresourcefile.c:599
+#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983
+#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253
+#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599
#: gio/gresourcefile.c:736
#, c-format
msgid "The resource at “%s” does not exist"
msgstr "The resource at “%s” does not exist"
-#: gio/gresource.c:837
+#: gio/gresource.c:848
#, c-format
msgid "The resource at “%s” failed to decompress"
msgstr "The resource at “%s” failed to decompress"
@@ -3726,7 +3838,7 @@ msgstr "Invalid socket, initialization failed due to: %s"
msgid "Socket is already closed"
msgstr "Socket is already closed"
-#: gio/gsocket.c:443 gio/gsocket.c:3180 gio/gsocket.c:4403 gio/gsocket.c:4461
+#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478
msgid "Socket I/O timed out"
msgstr "Socket I/O timed out"
@@ -3735,176 +3847,182 @@ msgstr "Socket I/O timed out"
msgid "creating GSocket from fd: %s"
msgstr "creating GSocket from fd: %s"
-#: gio/gsocket.c:607 gio/gsocket.c:661 gio/gsocket.c:668
+#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678
#, c-format
msgid "Unable to create socket: %s"
msgstr "Unable to create socket: %s"
-#: gio/gsocket.c:661
+#: gio/gsocket.c:671
msgid "Unknown family was specified"
msgstr "Unknown family was specified"
-#: gio/gsocket.c:668
+#: gio/gsocket.c:678
msgid "Unknown protocol was specified"
msgstr "Unknown protocol was specified"
-#: gio/gsocket.c:1159
+#: gio/gsocket.c:1169
#, c-format
msgid "Cannot use datagram operations on a non-datagram socket."
msgstr "Cannot use datagram operations on a non-datagram socket."
-#: gio/gsocket.c:1176
+#: gio/gsocket.c:1186
#, c-format
msgid "Cannot use datagram operations on a socket with a timeout set."
msgstr "Cannot use datagram operations on a socket with a timeout set."
-#: gio/gsocket.c:1983
+#: gio/gsocket.c:1993
#, c-format
msgid "could not get local address: %s"
msgstr "could not get local address: %s"
-#: gio/gsocket.c:2029
+#: gio/gsocket.c:2039
#, c-format
msgid "could not get remote address: %s"
msgstr "could not get remote address: %s"
-#: gio/gsocket.c:2095
+#: gio/gsocket.c:2105
#, c-format
msgid "could not listen: %s"
msgstr "could not listen: %s"
-#: gio/gsocket.c:2199
+#: gio/gsocket.c:2209
#, c-format
msgid "Error binding to address %s: %s"
msgstr "Error binding to address %s: %s"
-#: gio/gsocket.c:2375 gio/gsocket.c:2412 gio/gsocket.c:2522 gio/gsocket.c:2547
-#: gio/gsocket.c:2610 gio/gsocket.c:2668 gio/gsocket.c:2686
+#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557
+#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696
#, c-format
msgid "Error joining multicast group: %s"
msgstr "Error joining multicast group: %s"
-#: gio/gsocket.c:2376 gio/gsocket.c:2413 gio/gsocket.c:2523 gio/gsocket.c:2548
-#: gio/gsocket.c:2611 gio/gsocket.c:2669 gio/gsocket.c:2687
+#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558
+#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697
#, c-format
msgid "Error leaving multicast group: %s"
msgstr "Error leaving multicast group: %s"
-#: gio/gsocket.c:2377
+#: gio/gsocket.c:2387
msgid "No support for source-specific multicast"
msgstr "No support for source-specific multicast"
-#: gio/gsocket.c:2524
+#: gio/gsocket.c:2534
msgid "Unsupported socket family"
msgstr "Unsupported socket family"
-#: gio/gsocket.c:2549
+#: gio/gsocket.c:2559
msgid "source-specific not an IPv4 address"
msgstr "source-specific not an IPv4 address"
-#: gio/gsocket.c:2573
+#: gio/gsocket.c:2583
#, c-format
msgid "Interface name too long"
msgstr "Interface name too long"
-#: gio/gsocket.c:2586 gio/gsocket.c:2636
+#: gio/gsocket.c:2596 gio/gsocket.c:2646
#, c-format
msgid "Interface not found: %s"
msgstr "Interface not found: %s"
-#: gio/gsocket.c:2612
+#: gio/gsocket.c:2622
msgid "No support for IPv4 source-specific multicast"
msgstr "No support for IPv4 source-specific multicast"
-#: gio/gsocket.c:2670
+#: gio/gsocket.c:2680
msgid "No support for IPv6 source-specific multicast"
msgstr "No support for IPv6 source-specific multicast"
-#: gio/gsocket.c:2879
+#: gio/gsocket.c:2889
#, c-format
msgid "Error accepting connection: %s"
msgstr "Error accepting connection: %s"
-#: gio/gsocket.c:3005
+#: gio/gsocket.c:3015
msgid "Connection in progress"
msgstr "Connection in progress"
-#: gio/gsocket.c:3056
+#: gio/gsocket.c:3066
msgid "Unable to get pending error: "
msgstr "Unable to get pending error: "
-#: gio/gsocket.c:3245
+#: gio/gsocket.c:3255
#, c-format
msgid "Error receiving data: %s"
msgstr "Error receiving data: %s"
-#: gio/gsocket.c:3442
+#: gio/gsocket.c:3452
#, c-format
msgid "Error sending data: %s"
msgstr "Error sending data: %s"
-#: gio/gsocket.c:3629
+#: gio/gsocket.c:3639
#, c-format
msgid "Unable to shutdown socket: %s"
msgstr "Unable to shutdown socket: %s"
-#: gio/gsocket.c:3710
+#: gio/gsocket.c:3720
#, c-format
msgid "Error closing socket: %s"
msgstr "Error closing socket: %s"
-#: gio/gsocket.c:4396
+#: gio/gsocket.c:4413
#, c-format
msgid "Waiting for socket condition: %s"
msgstr "Waiting for socket condition: %s"
-#: gio/gsocket.c:4774 gio/gsocket.c:4776 gio/gsocket.c:4923 gio/gsocket.c:5008
-#: gio/gsocket.c:5186 gio/gsocket.c:5226 gio/gsocket.c:5228
+#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833
+#, c-format
+#| msgid "Error sending message: %s"
+msgid "Unable to send message: %s"
+msgstr "Unable to send message: %s"
+
+#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834
+msgid "Message vectors too large"
+msgstr "Message vectors too large"
+
+#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084
+#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304
#, c-format
msgid "Error sending message: %s"
msgstr "Error sending message: %s"
-#: gio/gsocket.c:4950
+#: gio/gsocket.c:5026
msgid "GSocketControlMessage not supported on Windows"
msgstr "GSocketControlMessage not supported on Windows"
-#: gio/gsocket.c:5419 gio/gsocket.c:5492 gio/gsocket.c:5718
+#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797
#, c-format
msgid "Error receiving message: %s"
msgstr "Error receiving message: %s"
-#: gio/gsocket.c:5990 gio/gsocket.c:6038
+#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "Unable to read socket credentials: %s"
-#: gio/gsocket.c:6047
+#: gio/gsocket.c:6136
msgid "g_socket_get_credentials not implemented for this OS"
msgstr "g_socket_get_credentials not implemented for this OS"
-#: gio/gsocketclient.c:182
+#: gio/gsocketclient.c:191
#, c-format
msgid "Could not connect to proxy server %s: "
msgstr "Could not connect to proxy server %s: "
-#: gio/gsocketclient.c:196
+#: gio/gsocketclient.c:205
#, c-format
msgid "Could not connect to %s: "
msgstr "Could not connect to %s: "
-#: gio/gsocketclient.c:198
+#: gio/gsocketclient.c:207
msgid "Could not connect: "
msgstr "Could not connect: "
-#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866
-msgid "Unknown error on connect"
-msgstr "Unknown error on connect"
-
-#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668
+#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749
msgid "Proxying over a non-TCP connection is not supported."
msgstr "Proxying over a non-TCP connection is not supported."
-#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698
+#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778
#, c-format
msgid "Proxy protocol “%s” is not supported."
msgstr "Proxy protocol “%s” is not supported."
@@ -4035,26 +4153,30 @@ msgstr "Temporarily unable to resolve “%s”"
msgid "Error resolving “%s”"
msgstr "Error resolving “%s”"
-#: gio/gtlscertificate.c:243
+#: gio/gtlscertificate.c:298
msgid "No PEM-encoded private key found"
msgstr "No PEM-encoded private key found"
-#: gio/gtlscertificate.c:253
+#: gio/gtlscertificate.c:308
msgid "Cannot decrypt PEM-encoded private key"
msgstr "Cannot decrypt PEM-encoded private key"
-#: gio/gtlscertificate.c:264
+#: gio/gtlscertificate.c:319
msgid "Could not parse PEM-encoded private key"
msgstr "Could not parse PEM-encoded private key"
-#: gio/gtlscertificate.c:291
+#: gio/gtlscertificate.c:346
msgid "No PEM-encoded certificate found"
msgstr "No PEM-encoded certificate found"
-#: gio/gtlscertificate.c:300
+#: gio/gtlscertificate.c:355
msgid "Could not parse PEM-encoded certificate"
msgstr "Could not parse PEM-encoded certificate"
+#: gio/gtlscertificate.c:710
+msgid "This GTlsBackend does not support creating PKCS #11 certificates"
+msgstr "This GTlsBackend does not support creating PKCS #11 certificates"
+
#: gio/gtlspassword.c:111
msgid ""
"This is the last chance to enter the password correctly before your access "
@@ -4081,8 +4203,10 @@ msgstr "The password entered is incorrect."
#, c-format
msgid "Expecting 1 control message, got %d"
msgid_plural "Expecting 1 control message, got %d"
-msgstr[0] "Expecting 1 control message, got %d"
-msgstr[1] "Expecting 1 control message, got %d"
+msgstr[0] "‫Expecting 1 control message, got %d"
+msgstr[1] "‫Expecting 1 control message, got %d"
+msgstr[2] "‫Expecting 1 control message, got %d"
+msgstr[3] "‫Expecting 1 control message, got %d"
#: gio/gunixconnection.c:182 gio/gunixconnection.c:591
msgid "Unexpected type of ancillary data"
@@ -4092,8 +4216,18 @@ msgstr "Unexpected type of ancillary data"
#, c-format
msgid "Expecting one fd, but got %d\n"
msgid_plural "Expecting one fd, but got %d\n"
-msgstr[0] "Expecting one fd, but got %d\n"
-msgstr[1] "Expecting one fd, but got %d\n"
+msgstr[0] ""
+"‫Expecting one fd, but got %d\n"
+"‬\n"
+msgstr[1] ""
+"‫Expecting one fd, but got %d\n"
+"‬\n"
+msgstr[2] ""
+"‫Expecting one fd, but got %d\n"
+"‬\n"
+msgstr[3] ""
+"‫Expecting one fd, but got %d\n"
+"‬\n"
#: gio/gunixconnection.c:219
msgid "Received invalid fd"
@@ -4101,7 +4235,7 @@ msgstr "Received invalid fd"
#: gio/gunixconnection.c:363
msgid "Error sending credentials: "
-msgstr "Error sending data: %s"
+msgstr "Error sending credentials: "
#: gio/gunixconnection.c:520
#, c-format
@@ -4129,24 +4263,24 @@ msgstr "Not expecting control message, but got %d"
msgid "Error while disabling SO_PASSCRED: %s"
msgstr "Error while disabling SO_PASSCRED: %s"
-#: gio/gunixinputstream.c:362 gio/gunixinputstream.c:383
+#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378
#, c-format
msgid "Error reading from file descriptor: %s"
msgstr "Error reading from file descriptor: %s"
-#: gio/gunixinputstream.c:416 gio/gunixoutputstream.c:525
+#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520
#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204
#, c-format
msgid "Error closing file descriptor: %s"
msgstr "Error closing file descriptor: %s"
-#: gio/gunixmounts.c:2755 gio/gunixmounts.c:2808
+#: gio/gunixmounts.c:2780 gio/gunixmounts.c:2833
msgid "Filesystem root"
msgstr "Filesystem root"
-#: gio/gunixoutputstream.c:362 gio/gunixoutputstream.c:382
-#: gio/gunixoutputstream.c:469 gio/gunixoutputstream.c:489
-#: gio/gunixoutputstream.c:635
+#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377
+#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484
+#: gio/gunixoutputstream.c:630
#, c-format
msgid "Error writing to file descriptor: %s"
msgstr "Error writing to file descriptor: %s"
@@ -4183,7 +4317,7 @@ msgstr "Error writing to file: %s"
#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347
msgid "Not enough memory"
-msgstr "out of memory"
+msgstr "Not enough memory"
#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354
#, c-format
@@ -4350,25 +4484,25 @@ msgid "The pathname “%s” is not an absolute path"
msgstr "The pathname “%s” is not an absolute path"
#. Translators: this is the preferred format for expressing the date and the time
-#: glib/gdatetime.c:220
+#: glib/gdatetime.c:226
msgctxt "GDateTime"
msgid "%a %b %e %H:%M:%S %Y"
msgstr "%Z %H:%M:%S %Y %b %d %a"
#. Translators: this is the preferred format for expressing the date
-#: glib/gdatetime.c:223
+#: glib/gdatetime.c:229
msgctxt "GDateTime"
msgid "%m/%d/%y"
msgstr "%d/%m/%y"
#. Translators: this is the preferred format for expressing the time
-#: glib/gdatetime.c:226
+#: glib/gdatetime.c:232
msgctxt "GDateTime"
msgid "%H:%M:%S"
msgstr "%H:%M:%S"
#. Translators: this is the preferred format for expressing 12 hour time
-#: glib/gdatetime.c:229
+#: glib/gdatetime.c:235
msgctxt "GDateTime"
msgid "%I:%M:%S %p"
msgstr "%I:%M:%S %P"
@@ -4389,62 +4523,62 @@ msgstr "%I:%M:%S %P"
#. * non-European) there is no difference between the standalone and
#. * complete date form.
#.
-#: glib/gdatetime.c:268
+#: glib/gdatetime.c:274
msgctxt "full month name"
msgid "January"
msgstr "ינואר"
-#: glib/gdatetime.c:270
+#: glib/gdatetime.c:276
msgctxt "full month name"
msgid "February"
msgstr "פברואר"
-#: glib/gdatetime.c:272
+#: glib/gdatetime.c:278
msgctxt "full month name"
msgid "March"
msgstr "מרץ"
-#: glib/gdatetime.c:274
+#: glib/gdatetime.c:280
msgctxt "full month name"
msgid "April"
msgstr "אפריל"
-#: glib/gdatetime.c:276
+#: glib/gdatetime.c:282
msgctxt "full month name"
msgid "May"
msgstr "מאי"
-#: glib/gdatetime.c:278
+#: glib/gdatetime.c:284
msgctxt "full month name"
msgid "June"
msgstr "יוני"
-#: glib/gdatetime.c:280
+#: glib/gdatetime.c:286
msgctxt "full month name"
msgid "July"
msgstr "יולי"
-#: glib/gdatetime.c:282
+#: glib/gdatetime.c:288
msgctxt "full month name"
msgid "August"
msgstr "אוגוסט"
-#: glib/gdatetime.c:284
+#: glib/gdatetime.c:290
msgctxt "full month name"
msgid "September"
msgstr "ספטמבר"
-#: glib/gdatetime.c:286
+#: glib/gdatetime.c:292
msgctxt "full month name"
msgid "October"
msgstr "אוקטובר"
-#: glib/gdatetime.c:288
+#: glib/gdatetime.c:294
msgctxt "full month name"
msgid "November"
msgstr "נובמבר"
-#: glib/gdatetime.c:290
+#: glib/gdatetime.c:296
msgctxt "full month name"
msgid "December"
msgstr "דצמבר"
@@ -4466,132 +4600,132 @@ msgstr "דצמבר"
#. * other platform. Here are abbreviated month names in a form
#. * appropriate when they are used standalone.
#.
-#: glib/gdatetime.c:322
+#: glib/gdatetime.c:328
msgctxt "abbreviated month name"
msgid "Jan"
msgstr "ינו"
-#: glib/gdatetime.c:324
+#: glib/gdatetime.c:330
msgctxt "abbreviated month name"
msgid "Feb"
msgstr "פבר"
-#: glib/gdatetime.c:326
+#: glib/gdatetime.c:332
msgctxt "abbreviated month name"
msgid "Mar"
msgstr "מרץ"
-#: glib/gdatetime.c:328
+#: glib/gdatetime.c:334
msgctxt "abbreviated month name"
msgid "Apr"
msgstr "אפר"
-#: glib/gdatetime.c:330
+#: glib/gdatetime.c:336
msgctxt "abbreviated month name"
msgid "May"
msgstr "מאי"
-#: glib/gdatetime.c:332
+#: glib/gdatetime.c:338
msgctxt "abbreviated month name"
msgid "Jun"
msgstr "יונ"
-#: glib/gdatetime.c:334
+#: glib/gdatetime.c:340
msgctxt "abbreviated month name"
msgid "Jul"
msgstr "יול"
-#: glib/gdatetime.c:336
+#: glib/gdatetime.c:342
msgctxt "abbreviated month name"
msgid "Aug"
msgstr "אוג"
-#: glib/gdatetime.c:338
+#: glib/gdatetime.c:344
msgctxt "abbreviated month name"
msgid "Sep"
msgstr "ספט"
-#: glib/gdatetime.c:340
+#: glib/gdatetime.c:346
msgctxt "abbreviated month name"
msgid "Oct"
msgstr "אוק"
-#: glib/gdatetime.c:342
+#: glib/gdatetime.c:348
msgctxt "abbreviated month name"
msgid "Nov"
msgstr "נוב"
-#: glib/gdatetime.c:344
+#: glib/gdatetime.c:350
msgctxt "abbreviated month name"
msgid "Dec"
msgstr "דצמ"
-#: glib/gdatetime.c:359
+#: glib/gdatetime.c:365
msgctxt "full weekday name"
msgid "Monday"
msgstr "יום שני"
-#: glib/gdatetime.c:361
+#: glib/gdatetime.c:367
msgctxt "full weekday name"
msgid "Tuesday"
msgstr "יום שלישי"
-#: glib/gdatetime.c:363
+#: glib/gdatetime.c:369
msgctxt "full weekday name"
msgid "Wednesday"
msgstr "יום רביעי"
-#: glib/gdatetime.c:365
+#: glib/gdatetime.c:371
msgctxt "full weekday name"
msgid "Thursday"
msgstr "יום חמישי"
-#: glib/gdatetime.c:367
+#: glib/gdatetime.c:373
msgctxt "full weekday name"
msgid "Friday"
msgstr "יום שישי"
-#: glib/gdatetime.c:369
+#: glib/gdatetime.c:375
msgctxt "full weekday name"
msgid "Saturday"
msgstr "שבת"
-#: glib/gdatetime.c:371
+#: glib/gdatetime.c:377
msgctxt "full weekday name"
msgid "Sunday"
msgstr "יום ראשון"
-#: glib/gdatetime.c:386
+#: glib/gdatetime.c:392
msgctxt "abbreviated weekday name"
msgid "Mon"
msgstr "ב׳"
-#: glib/gdatetime.c:388
+#: glib/gdatetime.c:394
msgctxt "abbreviated weekday name"
msgid "Tue"
msgstr "ג׳"
-#: glib/gdatetime.c:390
+#: glib/gdatetime.c:396
msgctxt "abbreviated weekday name"
msgid "Wed"
msgstr "ד׳"
-#: glib/gdatetime.c:392
+#: glib/gdatetime.c:398
msgctxt "abbreviated weekday name"
msgid "Thu"
msgstr "ה"
-#: glib/gdatetime.c:394
+#: glib/gdatetime.c:400
msgctxt "abbreviated weekday name"
msgid "Fri"
msgstr "ו׳"
-#: glib/gdatetime.c:396
+#: glib/gdatetime.c:402
msgctxt "abbreviated weekday name"
msgid "Sat"
msgstr "ש׳"
-#: glib/gdatetime.c:398
+#: glib/gdatetime.c:404
msgctxt "abbreviated weekday name"
msgid "Sun"
msgstr "א׳"
@@ -4613,62 +4747,62 @@ msgstr "א׳"
#. * (western European, non-European) there is no difference between the
#. * standalone and complete date form.
#.
-#: glib/gdatetime.c:462
+#: glib/gdatetime.c:468
msgctxt "full month name with day"
msgid "January"
msgstr "ינואר"
-#: glib/gdatetime.c:464
+#: glib/gdatetime.c:470
msgctxt "full month name with day"
msgid "February"
msgstr "פברואר"
-#: glib/gdatetime.c:466
+#: glib/gdatetime.c:472
msgctxt "full month name with day"
msgid "March"
msgstr "מרץ"
-#: glib/gdatetime.c:468
+#: glib/gdatetime.c:474
msgctxt "full month name with day"
msgid "April"
msgstr "אפריל"
-#: glib/gdatetime.c:470
+#: glib/gdatetime.c:476
msgctxt "full month name with day"
msgid "May"
msgstr "מאי"
-#: glib/gdatetime.c:472
+#: glib/gdatetime.c:478
msgctxt "full month name with day"
msgid "June"
msgstr "יוני"
-#: glib/gdatetime.c:474
+#: glib/gdatetime.c:480
msgctxt "full month name with day"
msgid "July"
msgstr "יולי"
-#: glib/gdatetime.c:476
+#: glib/gdatetime.c:482
msgctxt "full month name with day"
msgid "August"
msgstr "אוגוסט"
-#: glib/gdatetime.c:478
+#: glib/gdatetime.c:484
msgctxt "full month name with day"
msgid "September"
msgstr "ספטמבר"
-#: glib/gdatetime.c:480
+#: glib/gdatetime.c:486
msgctxt "full month name with day"
msgid "October"
msgstr "אוקטובר"
-#: glib/gdatetime.c:482
+#: glib/gdatetime.c:488
msgctxt "full month name with day"
msgid "November"
msgstr "נובמבר"
-#: glib/gdatetime.c:484
+#: glib/gdatetime.c:490
msgctxt "full month name with day"
msgid "December"
msgstr "דצמבר"
@@ -4690,74 +4824,74 @@ msgstr "דצמבר"
#. * month names almost ready to copy and paste here. In other systems
#. * due to a bug the result is incorrect in some languages.
#.
-#: glib/gdatetime.c:549
+#: glib/gdatetime.c:555
msgctxt "abbreviated month name with day"
msgid "Jan"
msgstr "ינו"
-#: glib/gdatetime.c:551
+#: glib/gdatetime.c:557
msgctxt "abbreviated month name with day"
msgid "Feb"
msgstr "פבר"
-#: glib/gdatetime.c:553
+#: glib/gdatetime.c:559
msgctxt "abbreviated month name with day"
msgid "Mar"
msgstr "מרץ"
-#: glib/gdatetime.c:555
+#: glib/gdatetime.c:561
msgctxt "abbreviated month name with day"
msgid "Apr"
msgstr "אפר"
-#: glib/gdatetime.c:557
+#: glib/gdatetime.c:563
msgctxt "abbreviated month name with day"
msgid "May"
msgstr "מאי"
-#: glib/gdatetime.c:559
+#: glib/gdatetime.c:565
msgctxt "abbreviated month name with day"
msgid "Jun"
msgstr "יונ"
-#: glib/gdatetime.c:561
+#: glib/gdatetime.c:567
msgctxt "abbreviated month name with day"
msgid "Jul"
msgstr "יול"
-#: glib/gdatetime.c:563
+#: glib/gdatetime.c:569
msgctxt "abbreviated month name with day"
msgid "Aug"
msgstr "אוג"
-#: glib/gdatetime.c:565
+#: glib/gdatetime.c:571
msgctxt "abbreviated month name with day"
msgid "Sep"
msgstr "ספט"
-#: glib/gdatetime.c:567
+#: glib/gdatetime.c:573
msgctxt "abbreviated month name with day"
msgid "Oct"
msgstr "אוק"
-#: glib/gdatetime.c:569
+#: glib/gdatetime.c:575
msgctxt "abbreviated month name with day"
msgid "Nov"
msgstr "נוב"
-#: glib/gdatetime.c:571
+#: glib/gdatetime.c:577
msgctxt "abbreviated month name with day"
msgid "Dec"
msgstr "דצמ"
#. Translators: 'before midday' indicator
-#: glib/gdatetime.c:588
+#: glib/gdatetime.c:594
msgctxt "GDateTime"
msgid "AM"
msgstr "AM"
#. Translators: 'after midday' indicator
-#: glib/gdatetime.c:591
+#: glib/gdatetime.c:597
msgctxt "GDateTime"
msgid "PM"
msgstr "PM"
@@ -4771,8 +4905,10 @@ msgstr "Error opening directory “%s”: %s"
#, c-format
msgid "Could not allocate %lu byte to read file “%s”"
msgid_plural "Could not allocate %lu bytes to read file “%s”"
-msgstr[0] "Could not allocate %lu bytes to read file “%s”"
-msgstr[1] "Could not allocate %lu bytes to read file \"%s\""
+msgstr[0] "‫Could not allocate %lu byte to read file “%s”"
+msgstr[1] "‫Could not allocate %lu bytes to read file “%s”"
+msgstr[2] "‫Could not allocate %lu bytes to read file “%s”"
+msgstr[3] "‫Could not allocate %lu bytes to read file “%s”"
#: glib/gfileutils.c:754
#, c-format
@@ -4789,79 +4925,79 @@ msgstr "File “%s” is too large"
msgid "Failed to read from file “%s”: %s"
msgstr "Failed to read from file “%s”: %s"
-#: glib/gfileutils.c:902 glib/gfileutils.c:974 glib/gfileutils.c:1466
+#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468
#, c-format
msgid "Failed to open file “%s”: %s"
msgstr "Failed to open file “%s”: %s"
-#: glib/gfileutils.c:914
+#: glib/gfileutils.c:917
#, c-format
msgid "Failed to get attributes of file “%s”: fstat() failed: %s"
msgstr "Failed to get attributes of file “%s”: fstat() failed: %s"
-#: glib/gfileutils.c:944
+#: glib/gfileutils.c:948
#, c-format
msgid "Failed to open file “%s”: fdopen() failed: %s"
msgstr "Failed to open file “%s”: fdopen() failed: %s"
-#: glib/gfileutils.c:1044
+#: glib/gfileutils.c:1049
#, c-format
msgid "Failed to rename file “%s” to “%s”: g_rename() failed: %s"
msgstr "Failed to rename file “%s” to “%s”: g_rename() failed: %s"
-#: glib/gfileutils.c:1169
+#: glib/gfileutils.c:1175
#, c-format
msgid "Failed to write file “%s”: write() failed: %s"
msgstr "Failed to write file “%s”: write() failed: %s"
-#: glib/gfileutils.c:1189
+#: glib/gfileutils.c:1196
#, c-format
msgid "Failed to write file “%s”: fsync() failed: %s"
msgstr "Failed to write file “%s”: fsync() failed: %s"
-#: glib/gfileutils.c:1357 glib/gfileutils.c:1769
+#: glib/gfileutils.c:1357 glib/gfileutils.c:1772
#, c-format
msgid "Failed to create file “%s”: %s"
msgstr "Failed to create file “%s”: %s"
-#: glib/gfileutils.c:1401
+#: glib/gfileutils.c:1402
#, c-format
msgid "Existing file “%s” could not be removed: g_unlink() failed: %s"
msgstr "Existing file “%s” could not be removed: g_unlink() failed: %s"
-#: glib/gfileutils.c:1735
+#: glib/gfileutils.c:1737
#, c-format
msgid "Template “%s” invalid, should not contain a “%s”"
msgstr "Template “%s” invalid, should not contain a “%s”"
-#: glib/gfileutils.c:1748
+#: glib/gfileutils.c:1750
#, c-format
msgid "Template “%s” doesn’t contain XXXXXX"
msgstr "Template “%s” doesn’t contain XXXXXX"
-#: glib/gfileutils.c:2306 glib/gfileutils.c:2334
+#: glib/gfileutils.c:2310 glib/gfileutils.c:2339
#, c-format
msgid "Failed to read the symbolic link “%s”: %s"
msgstr "Failed to read the symbolic link “%s”: %s"
-#: glib/giochannel.c:1396
+#: glib/giochannel.c:1405
#, c-format
msgid "Could not open converter from “%s” to “%s”: %s"
msgstr "Could not open converter from “%s” to “%s”: %s"
-#: glib/giochannel.c:1749
+#: glib/giochannel.c:1758
msgid "Can’t do a raw read in g_io_channel_read_line_string"
msgstr "Can’t do a raw read in g_io_channel_read_line_string"
-#: glib/giochannel.c:1796 glib/giochannel.c:2054 glib/giochannel.c:2141
+#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150
msgid "Leftover unconverted data in read buffer"
msgstr "Left over unconverted data in read buffer"
-#: glib/giochannel.c:1877 glib/giochannel.c:1954
+#: glib/giochannel.c:1886 glib/giochannel.c:1963
msgid "Channel terminates in a partial character"
msgstr "Channel terminates in a partial character"
-#: glib/giochannel.c:1940
+#: glib/giochannel.c:1949
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "Can’t do a raw read in g_io_channel_read_to_end"
@@ -4873,57 +5009,57 @@ msgstr "Valid key file could not be found in search dirs"
msgid "Not a regular file"
msgstr "Not a regular file"
-#: glib/gkeyfile.c:1275
+#: glib/gkeyfile.c:1281
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
msgstr ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
-#: glib/gkeyfile.c:1332
+#: glib/gkeyfile.c:1338
#, c-format
msgid "Invalid group name: %s"
msgstr "Invalid group name: %s"
-#: glib/gkeyfile.c:1354
+#: glib/gkeyfile.c:1360
msgid "Key file does not start with a group"
msgstr "Key file does not start with a group"
-#: glib/gkeyfile.c:1380
+#: glib/gkeyfile.c:1386
#, c-format
msgid "Invalid key name: %s"
msgstr "Invalid key name: %s"
-#: glib/gkeyfile.c:1407
+#: glib/gkeyfile.c:1413
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "Key file contains unsupported encoding “%s”"
-#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276
-#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602
-#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044
+#: glib/gkeyfile.c:1662 glib/gkeyfile.c:1835 glib/gkeyfile.c:3288
+#: glib/gkeyfile.c:3352 glib/gkeyfile.c:3482 glib/gkeyfile.c:3614
+#: glib/gkeyfile.c:3760 glib/gkeyfile.c:3995 glib/gkeyfile.c:4062
#, c-format
msgid "Key file does not have group “%s”"
msgstr "Key file does not have group “%s”"
-#: glib/gkeyfile.c:1778
+#: glib/gkeyfile.c:1790
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "Key file does not have key “%s” in group “%s”"
-#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056
+#: glib/gkeyfile.c:1952 glib/gkeyfile.c:2068
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "Key file contains key “%s” with value “%s” which is not UTF-8"
-#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518
+#: glib/gkeyfile.c:1972 glib/gkeyfile.c:2088 glib/gkeyfile.c:2530
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
msgstr ""
"Key file contains key “%s” which has a value that cannot be interpreted."
-#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105
+#: glib/gkeyfile.c:2748 glib/gkeyfile.c:3117
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
@@ -4932,36 +5068,36 @@ msgstr ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
"interpreted."
-#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891
+#: glib/gkeyfile.c:2826 glib/gkeyfile.c:2903
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "Key “%s” in group “%s” has value “%s” where %s was expected"
-#: glib/gkeyfile.c:4284
+#: glib/gkeyfile.c:4305
msgid "Key file contains escape character at end of line"
msgstr "Key file contains escape character at end of line"
-#: glib/gkeyfile.c:4306
+#: glib/gkeyfile.c:4327
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "Key file contains invalid escape sequence “%s”"
-#: glib/gkeyfile.c:4450
+#: glib/gkeyfile.c:4471
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "Value “%s” cannot be interpreted as a number."
-#: glib/gkeyfile.c:4464
+#: glib/gkeyfile.c:4485
#, c-format
msgid "Integer value “%s” out of range"
msgstr "Integer value “%s” out of range"
-#: glib/gkeyfile.c:4497
+#: glib/gkeyfile.c:4518
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "Value “%s” cannot be interpreted as a float number."
-#: glib/gkeyfile.c:4536
+#: glib/gkeyfile.c:4557
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "Value “%s” cannot be interpreted as a boolean."
@@ -5246,12 +5382,12 @@ msgstr "Double value “%s” for %s out of range"
msgid "Error parsing option %s"
msgstr "Error parsing option %s"
-#: glib/goption.c:1570 glib/goption.c:1683
+#: glib/goption.c:1561 glib/goption.c:1674
#, c-format
msgid "Missing argument for %s"
msgstr "Missing·argument·for·%s"
-#: glib/goption.c:2194
+#: glib/goption.c:2185
#, c-format
msgid "Unknown option %s"
msgstr "Unknown option %s"
@@ -5645,82 +5781,82 @@ msgstr "Text ended before matching quote was found for %c. (The text was “%s
msgid "Text was empty (or contained only whitespace)"
msgstr "Text was empty (or contained only whitespace)"
-#: glib/gspawn.c:323
+#: glib/gspawn.c:308
#, c-format
msgid "Failed to read data from child process (%s)"
msgstr "Failed to read data from child process (%s)"
-#: glib/gspawn.c:468
+#: glib/gspawn.c:455
#, c-format
msgid "Unexpected error in reading data from a child process (%s)"
msgstr "Unexpected error in reading data from a child process (%s)"
-#: glib/gspawn.c:553
+#: glib/gspawn.c:540
#, c-format
msgid "Unexpected error in waitpid() (%s)"
msgstr "Unexpected error in waitpid() (%s)"
-#: glib/gspawn.c:1061 glib/gspawn-win32.c:1329
+#: glib/gspawn.c:1144 glib/gspawn-win32.c:1383
#, c-format
msgid "Child process exited with code %ld"
msgstr "Child process exited with code %ld"
-#: glib/gspawn.c:1069
+#: glib/gspawn.c:1152
#, c-format
msgid "Child process killed by signal %ld"
msgstr "Child process killed by signal %ld"
-#: glib/gspawn.c:1076
+#: glib/gspawn.c:1159
#, c-format
msgid "Child process stopped by signal %ld"
msgstr "Child process stopped by signal %ld"
-#: glib/gspawn.c:1083
+#: glib/gspawn.c:1166
#, c-format
msgid "Child process exited abnormally"
msgstr "Child process exited abnormally"
-#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1757 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
#, c-format
msgid "Failed to read from child pipe (%s)"
msgstr "Failed to read from child pipe (%s)"
-#: glib/gspawn.c:1788
+#: glib/gspawn.c:2059
#, c-format
msgid "Failed to spawn child process “%s” (%s)"
msgstr "Failed to spawn child process “%s” (%s)"
-#: glib/gspawn.c:1871
+#: glib/gspawn.c:2176
#, c-format
msgid "Failed to fork (%s)"
msgstr "Failed to fork (%s)"
-#: glib/gspawn.c:2026 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2336 glib/gspawn-win32.c:381
#, c-format
msgid "Failed to change to directory “%s” (%s)"
msgstr "Failed to change to directory “%s” (%s)"
-#: glib/gspawn.c:2036
+#: glib/gspawn.c:2346
#, c-format
msgid "Failed to execute child process “%s” (%s)"
msgstr "Failed to execute child process “%s” (%s)"
-#: glib/gspawn.c:2046
+#: glib/gspawn.c:2356
#, c-format
msgid "Failed to redirect output or input of child process (%s)"
msgstr "Failed to redirect output or input of child process (%s)"
-#: glib/gspawn.c:2055
+#: glib/gspawn.c:2365
#, c-format
msgid "Failed to fork child process (%s)"
msgstr "Failed to fork child process (%s)"
-#: glib/gspawn.c:2063
+#: glib/gspawn.c:2373
#, c-format
msgid "Unknown error executing child process “%s”"
msgstr "Unknown error executing child process “%s”"
-#: glib/gspawn.c:2087
+#: glib/gspawn.c:2397
#, c-format
msgid "Failed to read enough data from child pid pipe (%s)"
msgstr "Failed to read enough data from child pid pipe (%s)"
@@ -5744,27 +5880,27 @@ msgstr "Failed to execute child process (%s)"
msgid "Invalid program name: %s"
msgstr "Invalid program name: %s"
-#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725
+#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:757
#, c-format
msgid "Invalid string in argument vector at %d: %s"
msgstr "Invalid string in argument vector at %d: %s"
-#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740
+#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:772
#, c-format
msgid "Invalid string in environment: %s"
msgstr "Invalid string in environment: %s"
-#: glib/gspawn-win32.c:721
+#: glib/gspawn-win32.c:753
#, c-format
msgid "Invalid working directory: %s"
msgstr "Invalid working directory: %s"
-#: glib/gspawn-win32.c:783
+#: glib/gspawn-win32.c:815
#, c-format
msgid "Failed to execute helper program (%s)"
msgstr "Failed to execute helper program (%s)"
-#: glib/gspawn-win32.c:1056
+#: glib/gspawn-win32.c:1042
msgid ""
"Unexpected error in g_io_channel_win32_poll() reading data from a child "
"process"
@@ -5772,77 +5908,79 @@ msgstr ""
"Unexpected error in g_io_channel_win32_poll() reading data from a child "
"process"
-#: glib/gstrfuncs.c:3303 glib/gstrfuncs.c:3405
+#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440
msgid "Empty string is not a number"
msgstr "Empty string is not a number"
-#: glib/gstrfuncs.c:3327
+#: glib/gstrfuncs.c:3362
#, c-format
msgid "“%s” is not a signed number"
msgstr "“%s” is not a signed number"
-#: glib/gstrfuncs.c:3337 glib/gstrfuncs.c:3441
+#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Number “%s” is out of bounds [%s, %s]"
-#: glib/gstrfuncs.c:3431
+#: glib/gstrfuncs.c:3466
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "“%s” is not an unsigned number"
-#: glib/guri.c:313
+#: glib/guri.c:315
#, no-c-format
-#| msgid " (invalid encoding)"
msgid "Invalid %-encoding in URI"
msgstr "Invalid %-encoding in URI"
-#: glib/guri.c:330
+#: glib/guri.c:332
msgid "Illegal character in URI"
msgstr "Illegal character in URI"
-#: glib/guri.c:359
+#: glib/guri.c:366
msgid "Non-UTF-8 characters in URI"
msgstr "Non-UTF-8 characters in URI"
-#: glib/guri.c:462
+#: glib/guri.c:546
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "Invalid IPv6 address ‘%.*s’ in URI"
-#: glib/guri.c:524
+#: glib/guri.c:601
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "Illegal encoded IP address ‘%.*s’ in URI"
-#: glib/guri.c:558 glib/guri.c:570
+#: glib/guri.c:613
+#, c-format
+#| msgid "Illegal encoded IP address ‘%.*s’ in URI"
+msgid "Illegal internationalized hostname ‘%.*s’ in URI"
+msgstr "Illegal internationalized hostname ‘%.*s’ in URI"
+
+#: glib/guri.c:645 glib/guri.c:657
#, c-format
-#| msgid "Could not parse “%s” as IP address mask"
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "Could not parse port ‘%.*s’ in URI"
-#: glib/guri.c:577
+#: glib/guri.c:664
#, c-format
-#| msgid "Double value “%s” for %s out of range"
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "Port ‘%.*s’ in URI is out of range"
-#: glib/guri.c:1055 glib/guri.c:1119
+#: glib/guri.c:1224 glib/guri.c:1288
#, c-format
-#| msgid "The pathname “%s” is not an absolute path"
msgid "URI ‘%s’ is not an absolute URI"
msgstr "URI ‘%s’ is not an absolute URI"
-#: glib/guri.c:1061
+#: glib/guri.c:1230
#, c-format
msgid "URI ‘%s’ has no host component"
msgstr "URI ‘%s’ has no host component"
-#: glib/guri.c:1263
+#: glib/guri.c:1435
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI is not absolute, and no base URI was provided"
-#: glib/guri.c:2019
+#: glib/guri.c:2209
msgid "Missing ‘=’ and parameter value"
msgstr "Missing ‘=’ and parameter value"
@@ -5864,596 +6002,218 @@ msgid "Character out of range for UTF-16"
msgstr "Character out of range for UTF-16"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2756
+#: glib/gutils.c:2767
#, c-format
msgid "%.1f kB"
msgstr "%.1f ק״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2758
+#: glib/gutils.c:2769
#, c-format
msgid "%.1f MB"
msgstr "%.1f מ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2760
+#: glib/gutils.c:2771
#, c-format
msgid "%.1f GB"
msgstr "%.1f ג״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2762
+#: glib/gutils.c:2773
#, c-format
msgid "%.1f TB"
msgstr "%.1f ט״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2764
+#: glib/gutils.c:2775
#, c-format
msgid "%.1f PB"
msgstr "%.1f פ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2766
+#: glib/gutils.c:2777
#, c-format
msgid "%.1f EB"
msgstr "%.1f א״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2770
+#: glib/gutils.c:2781
#, c-format
msgid "%.1f KiB"
msgstr "%.1f קי״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2772
+#: glib/gutils.c:2783
#, c-format
msgid "%.1f MiB"
msgstr "%.1f מבי״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2774
+#: glib/gutils.c:2785
#, c-format
msgid "%.1f GiB"
msgstr "%.1f גיב״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2776
+#: glib/gutils.c:2787
#, c-format
msgid "%.1f TiB"
msgstr "%.1f טבי״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2778
+#: glib/gutils.c:2789
#, c-format
msgid "%.1f PiB"
msgstr "%.1f פבי״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2780
+#: glib/gutils.c:2791
#, c-format
msgid "%.1f EiB"
msgstr "%.1f אק״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2784
+#: glib/gutils.c:2795
#, c-format
msgid "%.1f kb"
msgstr "%.1f ק״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2786
+#: glib/gutils.c:2797
#, c-format
msgid "%.1f Mb"
msgstr "%.1f מ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2788
+#: glib/gutils.c:2799
#, c-format
msgid "%.1f Gb"
msgstr "%.1f ג״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2790
+#: glib/gutils.c:2801
#, c-format
msgid "%.1f Tb"
msgstr "%.1f ט״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2792
+#: glib/gutils.c:2803
#, c-format
msgid "%.1f Pb"
msgstr "%.1f פ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2794
+#: glib/gutils.c:2805
#, c-format
msgid "%.1f Eb"
msgstr "%.1f א״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2798
+#: glib/gutils.c:2809
#, c-format
msgid "%.1f Kib"
msgstr "%.1f ק״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2800
+#: glib/gutils.c:2811
#, c-format
msgid "%.1f Mib"
msgstr "%.1f מ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2802
+#: glib/gutils.c:2813
#, c-format
msgid "%.1f Gib"
msgstr "%.1f ג״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2804
+#: glib/gutils.c:2815
#, c-format
msgid "%.1f Tib"
msgstr "%.1f ט״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2806
+#: glib/gutils.c:2817
#, c-format
msgid "%.1f Pib"
msgstr "%.1f פ״ב"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2808
+#: glib/gutils.c:2819
#, c-format
msgid "%.1f Eib"
msgstr "%.1f א״ב"
-#: glib/gutils.c:2842 glib/gutils.c:2959
+#: glib/gutils.c:2853 glib/gutils.c:2970
#, c-format
msgid "%u byte"
msgid_plural "%u bytes"
msgstr[0] "בית אחד"
-msgstr[1] "%u בתים"
+msgstr[1] "שני בתים"
+msgstr[2] "‫%u בתים"
+msgstr[3] "‫%u בתים"
-#: glib/gutils.c:2846
+#: glib/gutils.c:2857
#, c-format
msgid "%u bit"
msgid_plural "%u bits"
msgstr[0] "סיבית אחת"
-msgstr[1] "%u סיביות"
+msgstr[1] "שתי סיביות"
+msgstr[2] "‫%u סיביות"
+msgstr[3] "‫%u סיביות"
#. Translators: the %s in "%s bytes" will always be replaced by a number.
-#: glib/gutils.c:2913
+#: glib/gutils.c:2924
#, c-format
msgid "%s byte"
msgid_plural "%s bytes"
msgstr[0] "בית אחד"
-msgstr[1] "%s בתים"
+msgstr[1] "שני בתים"
+msgstr[2] "‫%s בתים"
+msgstr[3] "‫%s בתים"
#. Translators: the %s in "%s bits" will always be replaced by a number.
-#: glib/gutils.c:2918
+#: glib/gutils.c:2929
#, c-format
msgid "%s bit"
msgid_plural "%s bits"
msgstr[0] "סיבית אחת"
-msgstr[1] "%s סיביות"
+msgstr[1] "שתי סיביות"
+msgstr[2] "‫%s סיביות"
+msgstr[3] "‫%s סיביות"
#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to
#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of
#. * compatibility. Users will not see this string unless a program is using this deprecated function.
#. * Please translate as literally as possible.
#.
-#: glib/gutils.c:2972
+#: glib/gutils.c:2983
#, c-format
msgid "%.1f KB"
msgstr "%.1f ק״ב"
-#: glib/gutils.c:2977
+#: glib/gutils.c:2988
#, c-format
msgid "%.1f MB"
msgstr "%.1f מ״ב"
-#: glib/gutils.c:2982
+#: glib/gutils.c:2993
#, c-format
msgid "%.1f GB"
msgstr "%.1f ג״ב"
-#: glib/gutils.c:2987
+#: glib/gutils.c:2998
#, c-format
msgid "%.1f TB"
msgstr "%.1f ט״ב"
-#: glib/gutils.c:2992
+#: glib/gutils.c:3003
#, c-format
msgid "%.1f PB"
msgstr "%.1f פ״ב"
-#: glib/gutils.c:2997
+#: glib/gutils.c:3008
#, c-format
msgid "%.1f EB"
msgstr "%.1f א״ב"
-
-#~ msgid "Error in address “%s” — the family attribute is malformed"
-#~ msgstr "Error in address “%s” — the family attribute is malformed"
-
-#~ msgid "No such method '%s'"
-#~ msgstr "No such method '%s'"
-
-#~ msgid ""
-#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment "
-#~ "variable - unknown value '%s'"
-#~ msgstr ""
-#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment "
-#~ "variable - unknown value '%s'"
-
-#~ msgid ""
-#~ "Message has %d file descriptors but the header field indicates %d file "
-#~ "descriptors"
-#~ msgstr ""
-#~ "Message has %d file descriptors but the header field indicates %d file "
-#~ "descriptors"
-
-#~ msgid "[ARGS...]"
-#~ msgstr "[ARGS...]"
-
-#~ msgid "Mounted %s at %s\n"
-#~ msgstr "Mounted %s at %s\n"
-
-#~ msgid "Failed to create temp file: %s"
-#~ msgstr "Failed to create temp file: %s"
-
-#~ msgid "; ignoring override for this key.\n"
-#~ msgstr "; ignoring override for this key.\n"
-
-#~ msgid " and --strict was specified; exiting.\n"
-#~ msgstr " and --strict was specified; exiting.\n"
-
-#~ msgid "Ignoring override for this key.\n"
-#~ msgstr "Ignoring override for this key.\n"
-
-#~ msgid "doing nothing.\n"
-#~ msgstr "doing nothing.\n"
-
-#~ msgid "Error: object path not specified.\n"
-#~ msgstr "Error: object path not specified.\n"
-
-#~ msgid "Error: signal not specified.\n"
-#~ msgstr "Error: signal not specified.\n"
-
-#~ msgid "Error: signal must be the fully-qualified name.\n"
-#~ msgstr "Error: signal must be the fully-qualified name.\n"
-
-#~ msgid "No files given"
-#~ msgstr "No files given"
-
-#~ msgid "Error getting writable attributes: %s\n"
-#~ msgstr "Error getting writable attributes: %s\n"
-
-#~ msgid "Error mounting location: %s\n"
-#~ msgstr "Error mounting location: %s\n"
-
-#~ msgid "Error unmounting mount: %s\n"
-#~ msgstr "Error unmounting mount: %s\n"
-
-#~ msgid "Error finding enclosing mount: %s\n"
-#~ msgstr "Error finding enclosing mount: %s\n"
-
-#~ msgid "Error ejecting mount: %s\n"
-#~ msgstr "Error ejecting mount: %s\n"
-
-#~ msgid "Error mounting %s: %s\n"
-#~ msgstr "Error mounting %s: %s\n"
-
-#~ msgid "No files to open"
-#~ msgstr "No files to open"
-
-#~ msgid "No files to delete"
-#~ msgstr "No files to delete"
-
-#~ msgid "Error setting attribute: %s\n"
-#~ msgstr "Error setting attribute: %s\n"
-
-#~ msgid "No such interface"
-#~ msgstr "No such interface"
-
-#~ msgid "Error creating directory '%s': %s"
-#~ msgstr "Error creating directory '%s': %s"
-
-#~ msgid "Error opening file '%s': %s"
-#~ msgstr "Error opening file '%s': %s"
-
-#~ msgid "Error reading file '%s': %s"
-#~ msgstr "Error reading file '%s': %s"
-
-#~ msgid "No locations gives"
-#~ msgstr "No locations gives"
-
-#~ msgid "Error renaming file: %s"
-#~ msgstr "Error renaming file: %s"
-
-#~ msgid "Can't open directory"
-#~ msgstr "Can't open directory"
-
-#~ msgid "Error opening file: %s"
-#~ msgstr "Error opening file: %s"
-
-#~ msgid "Error creating directory: %s"
-#~ msgstr "Error creating directory: %s"
-
-#~ msgid "association changes not supported on win32"
-#~ msgstr "association changes not supported on win32"
-
-#~ msgid "Association creation not supported on win32"
-#~ msgstr "Association creation not supported on win32"
-
-#~ msgid "Unable to find default local directory monitor type"
-#~ msgstr "Unable to find default local directory monitor type"
-
-#~ msgid "URIs not supported"
-#~ msgstr "URIs not supported"
-
-#~ msgid "Key file does not have key '%s'"
-#~ msgstr "Key file does not have key '%s'"
-
-#~ msgid ""
-#~ "Error processing input file with xmllint:\n"
-#~ "%s"
-#~ msgstr ""
-#~ "Error processing input file with xmllint:\n"
-#~ "%s"
-
-#~ msgid ""
-#~ "Error processing input file with to-pixdata:\n"
-#~ "%s"
-#~ msgstr ""
-#~ "Error processing input file with to-pixdata:\n"
-#~ "%s"
-
-#~ msgid "Unable to get pending error: %s"
-#~ msgstr "Unable to get pending error: %s"
-
-#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s"
-#~ msgstr "Failed to open file '%s' for writing: fdopen() failed: %s"
-
-#~ msgid "Failed to write file '%s': fflush() failed: %s"
-#~ msgstr "Failed to write file '%s': fflush() failed: %s"
-
-#~ msgid "Failed to close file '%s': fclose() failed: %s"
-#~ msgstr "Failed to close file '%s': fclose() failed: %s"
-
-#~ msgid "Incomplete data received for '%s'"
-#~ msgstr "Incomplete data received for '%s'"
-
-#~ msgid ""
-#~ "Unexpected option length while checking if SO_PASSCRED is enabled for "
-#~ "socket. Expected %d bytes, got %d"
-#~ msgstr ""
-#~ "Unexpected option length while checking if SO_PASSCRED is enabled for "
-#~ "socket. Expected %d bytes, got %d"
-
-#~ msgid "Abnormal program termination spawning command line '%s': %s"
-#~ msgstr "Abnormal program termination spawning command line '%s': %s"
-
-#~ msgid "Command line '%s' exited with non-zero exit status %d: %s"
-#~ msgstr "Command line '%s' exited with non-zero exit status %d: %s"
-
-#~ msgid "workspace limit for empty substrings reached"
-#~ msgstr "workspace limit for empty substrings reached"
-
-#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here"
-#~ msgstr "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here"
-
-#~ msgid "repeating a DEFINE group is not allowed"
-#~ msgstr "repeating a DEFINE group is not allowed"
-
-#~ msgid "No service record for '%s'"
-#~ msgstr "No service record for '%s'"
-
-#~ msgid "Error connecting: "
-#~ msgstr "Error connecting: "
-
-#~ msgid "Error connecting: %s"
-#~ msgstr "Error connecting: %s"
-
-#~ msgid "Error reading from unix: %s"
-#~ msgstr "Error reading from unix: %s"
-
-#~ msgid "Error writing to unix: %s"
-#~ msgstr "Error writing to unix: %s"
-
-#~ msgid "File is empty"
-#~ msgstr "File is empty"
-
-#~ msgid ""
-#~ "Key file contains key '%s' which has value that cannot be interpreted."
-#~ msgstr ""
-#~ "Key file contains key '%s' which has value that cannot be interpreted."
-
-#~ msgid "This option will be removed soon."
-#~ msgstr "This option will be removed soon."
-
-#~ msgid "Error stating file '%s': %s"
-#~ msgstr "Error stating file '%s': %s"
-
-#~ msgid "SOCKSv4 implementation limits username to %i characters"
-#~ msgstr "SOCKSv4 implementation limits username to %i characters"
-
-#~ msgid "SOCKSv4a implementation limits hostname to %i characters"
-#~ msgstr "SOCKSv4a implementation limits hostname to %i characters"
-
-#~ msgctxt "GDateTime"
-#~ msgid "am"
-#~ msgstr "am"
-
-#~ msgctxt "GDateTime"
-#~ msgid "pm"
-#~ msgstr "pm"
-
-#~ msgid "Failed to set value\n"
-#~ msgstr "Failed to set value\n"
-
-#~ msgid "Type of return value is incorrect, got '%s', expected '%s'"
-#~ msgstr "Type of return value is incorrect, got '%s', expected '%s'"
-
-#~ msgid ""
-#~ "Trying to set property %s of type %s but according to the expected "
-#~ "interface the type is %s"
-#~ msgstr ""
-#~ "Trying to set property %s of type %s but according to the expected "
-#~ "interface the type is %s"
-
-#~ msgid "No such schema '%s' specified in override file '%s'"
-#~ msgstr "No such schema '%s' specified in override file '%s'"
-
-#~ msgid ""
-#~ "Commands:\n"
-#~ " help Show this information\n"
-#~ " get Get the value of a key\n"
-#~ " set Set the value of a key\n"
-#~ " reset Reset the value of a key\n"
-#~ " monitor Monitor a key for changes\n"
-#~ " writable Check if a key is writable\n"
-#~ "\n"
-#~ "Use '%s COMMAND --help' to get help for individual commands.\n"
-#~ msgstr ""
-#~ "Commands:\n"
-#~ " help Show this information\n"
-#~ " get Get the value of a key\n"
-#~ " set Set the value of a key\n"
-#~ " reset Reset the value of a key\n"
-#~ " monitor Monitor a key for changes\n"
-#~ " writable Check if a key is writable\n"
-#~ "\n"
-#~ "Use '%s COMMAND --help' to get help for individual commands.\n"
-
-#~ msgid "Specify the path for the schema"
-#~ msgstr "Specify the path for the schema"
-
-#~ msgid ""
-#~ "Arguments:\n"
-#~ " SCHEMA The id of the schema\n"
-#~ " KEY The name of the key\n"
-#~ " VALUE The value to set key to, as a serialized GVariant\n"
-#~ msgstr ""
-#~ "Arguments:\n"
-#~ " SCHEMA The id of the schema\n"
-#~ " KEY The name of the key\n"
-#~ " VALUE The value to set key to, as a serialized GVariant\n"
-
-#~ msgid ""
-#~ "Monitor KEY for changes and print the changed values.\n"
-#~ "Monitoring will continue until the process is terminated."
-#~ msgstr ""
-#~ "Monitor KEY for changes and print the changed values.\n"
-#~ "Monitoring will continue until the process is terminated."
-
-#~ msgid "Error writing first 16 bytes of message to socket: "
-#~ msgstr "Error writing first 16 bytes of message to socket: "
-
-#~ msgid "The nonce-file '%s' was %lu bytes. Expected 16 bytes."
-#~ msgstr "The nonce-file '%s' was %lu bytes. Expected 16 bytes."
-
-#~ msgid "Encountered array of length %"
-#~ msgstr "Encountered array of length %"
-
-#~ msgid "Do not give error for empty directory"
-#~ msgstr "Can't move directory over directory"
-
-#~ msgid "Invalid UTF-8 sequence in input"
-#~ msgstr "Invalid sequence in conversion input"
-
-#~ msgid "Reached maximum data array limit"
-#~ msgstr "Reached maximum data array limit"
-
-#~ msgid "do not hide entries"
-#~ msgstr "do not hide entries"
-
-#~ msgid ""
-#~ "Character '%s' is not valid at the start of an entity name; the & "
-#~ "character begins an entity; if this ampersand isn't supposed to be an "
-#~ "entity, escape it as &amp;"
-#~ msgstr ""
-#~ "Character '%s' is not valid at the start of an entity name; the & "
-#~ "character begins an entity; if this ampersand isn't supposed to be an "
-#~ "entity, escape it as &amp;"
-
-#~ msgid "Character '%s' is not valid inside an entity name"
-#~ msgstr "Character '%s' is not valid inside an entity name"
-
-#~ msgid "Empty character reference; should include a digit such as &#454;"
-#~ msgstr "Empty character reference; should include a digit such as &#454;"
-
-#~ msgid "Unfinished entity reference"
-#~ msgstr "Unfinished entity reference"
-
-#~ msgid "Unfinished character reference"
-#~ msgstr "Unfinished character reference"
-
-#~ msgid "Invalid UTF-8 encoded text - overlong sequence"
-#~ msgstr "Invalid UTF-8 encoded text - overlong sequence"
-
-#~ msgid "Invalid UTF-8 encoded text - not a start char"
-#~ msgstr "Invalid UTF-8 encoded text - not a start char"
-
-#~ msgid "file"
-#~ msgstr "file"
-
-#~ msgid "The file containing the icon"
-#~ msgstr "The file containing the icon"
-
-#~ msgid "An array containing the icon names"
-#~ msgstr "An array containing the icon names"
-
-#~ msgid ""
-#~ "Whether to use default fallbacks found by shortening the name at '-' "
-#~ "characters. Ignores names after the first if multiple names are given."
-#~ msgstr ""
-#~ "Whether to use default fallbacks found by shortening the name at '-' "
-#~ "characters. Ignores names after the first if multiple names are given."
-
-#~ msgid "File descriptor"
-#~ msgstr "File descriptor"
-
-#~ msgid "The file descriptor to read from"
-#~ msgstr "The file descriptor to read from"
-
-#~ msgid "Close file descriptor"
-#~ msgstr "Close file descriptor"
-
-#~ msgid "Whether to close the file descriptor when the stream is closed"
-#~ msgstr "Whether to close the file descriptor when the stream is closed"
-
-#~ msgid "Can't load just created desktop file"
-#~ msgstr "Can't load just created desktop file"
-
-#~ msgid "Error creating backup link: %s"
-#~ msgstr "Error creating backup link: %s"
-
-#~ msgid "Too large count value passed to g_input_stream_read_async"
-#~ msgstr "Too large count value passed to g_input_stream_read_async"
-
-#~ msgid "Too large count value passed to g_input_stream_skip"
-#~ msgstr "Too large count value passed to g_input_stream_skip"
-
-#~ msgid "Too large count value passed to g_input_stream_skip_async"
-#~ msgstr "Too large count value passed to g_input_stream_skip_async"
-
-#~ msgid "Target file already exists"
-#~ msgstr "Target file already exists"
-
-#~ msgid "Too large count value passed to g_output_stream_write"
-#~ msgstr "Too large count value passed to g_output_stream_write"
-
-#~ msgid "Too large count value passed to g_output_stream_write_async"
-#~ msgstr "Too large count value passed to g_output_stream_write_async"
-
-#~ msgid "Could not change file mode: fork() failed: %s"
-#~ msgstr "Could not change file mode: fork() failed: %s"
-
-#~ msgid "Could not change file mode: chmod() failed: %s"
-#~ msgstr "Could not change file mode: chmod() failed: %s"
-
-#~ msgid "Could not change file mode: Child terminated by signal: %s"
-#~ msgstr "Could not change file mode: Child terminated by signal: %s"
-
-#~ msgid "Could not change file mode: Child terminated abnormally"
-#~ msgstr "Could not change file mode: Child terminated abnormally"
diff --git a/po/oc.po b/po/oc.po
index 3ebab6304..1d67b1a67 100644
--- a/po/oc.po
+++ b/po/oc.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: glib master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2021-06-24 15:19+0000\n"
-"PO-Revision-Date: 2021-07-06 21:57+0200\n"
+"POT-Creation-Date: 2021-03-22 11:48+0000\n"
+"PO-Revision-Date: 2021-04-29 20:01+0200\n"
"Last-Translator: Quentin PAGÈS\n"
"Language-Team: Tot en òc (totenoc.eu)\n"
"Language: oc\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.0\n"
+"X-Generator: Poedit 2.4.3\n"
"X-Launchpad-Export-Date: 2016-10-11 14:28+0000\n"
"X-Project-Style: gnome\n"
@@ -170,6 +170,8 @@ msgid "Arguments:\n"
msgstr "Paramètres :\n"
#: gio/gapplication-tool.c:135 gio/gio-tool.c:224
+#, fuzzy
+#| msgid "[ARGS...]"
msgid "[ARGS…]"
msgstr "[PARAMS...]"
@@ -180,12 +182,15 @@ msgstr "Comandas :\n"
#. Translators: do not translate 'help', but please translate 'COMMAND'.
#: gio/gapplication-tool.c:148
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Use '%s help COMMAND' to get detailed help.\n"
+#| "\n"
msgid ""
"Use “%s help COMMAND” to get detailed help.\n"
"\n"
msgstr ""
-"Utilizatz « %s help COMANDA » per obténer d’ajuda detalhada.\n"
+"Utilizatz « %s help COMANDA » per obténer de l'ajuda detalhada.\n"
"\n"
#: gio/gapplication-tool.c:167
@@ -198,13 +203,17 @@ msgstr ""
"\n"
#: gio/gapplication-tool.c:173
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid application id: '%s'\n"
msgid "invalid application id: “%s”\n"
-msgstr "identificant d’aplicacion invalid : « %s »\n"
+msgstr "identificant d'aplicacion invalid : « %s »\n"
#. Translators: %s is replaced with a command name like 'list-actions'
#: gio/gapplication-tool.c:184
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "'%s' takes no arguments\n"
+#| "\n"
msgid ""
"“%s” takes no arguments\n"
"\n"
@@ -227,13 +236,16 @@ msgid "action name must be given after application id\n"
msgstr "un nom d'accion deu èsser indicat aprèp l'identificant d'aplicacion\n"
#: gio/gapplication-tool.c:327
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "invalid action name: '%s'\n"
+#| "action names must consist of only alphanumerics, '-' and '.'\n"
msgid ""
"invalid action name: “%s”\n"
"action names must consist of only alphanumerics, “-” and “.”\n"
msgstr ""
-"nom d’accion invalid : « %s »\n"
-"los noms d’accions pòdon pas conténer que de caractèrs alfanumerics, « - » e "
+"nom d'accion invalid : « %s »\n"
+"los noms d'accions pòdon pas conténer que de caractèrs alfanumerics, « - » e "
"« . »\n"
#: gio/gapplication-tool.c:346
@@ -332,7 +344,8 @@ msgstr ""
"La conversion del jòc de caractèrs « %s » cap a « %s » es pas presa en carga"
#: gio/gcharsetconverter.c:460 glib/gconvert.c:325
-#, c-format
+#, fuzzy, c-format
+#| msgid "Could not open converter from '%s' to '%s'"
msgid "Could not open converter from “%s” to “%s”"
msgstr "Impossible de dobrir lo convertidor de « %s » cap a « %s »"
@@ -377,15 +390,17 @@ msgid "Unexpected early end-of-stream"
msgstr "Fin precòça de flux inesperada"
#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322
-#, c-format
+#, fuzzy, c-format
+#| msgid "Unsupported key '%s' in address entry '%s'"
msgid "Unsupported key “%s” in address entry “%s”"
-msgstr "Clau « %s » pas presa en carga dins l’element d’adreça « %s »"
+msgstr "Clau « %s » pas presa en carga dins l'element d'adreça « %s »"
#: gio/gdbusaddress.c:172
-#, c-format
+#, fuzzy, c-format
+#| msgid "Meaningless key/value pair combination in address entry '%s'"
msgid "Meaningless key/value pair combination in address entry “%s”"
msgstr ""
-"Combinason clau/valor sens significacion dins l’element d’adreça « %s »"
+"Combinason clau/valor sens significacion dins l'element d'adreça « %s »"
#: gio/gdbusaddress.c:181
#, fuzzy, c-format
@@ -447,70 +462,84 @@ msgstr ""
"de signe egal"
#: gio/gdbusaddress.c:517
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Error unescaping key or value in Key/Value pair %d, '%s', in address "
+#| "element '%s'"
msgid ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
"“%s”"
msgstr ""
-"Error al moment del desencodatge de la clau o de la valor dins lo parelh "
-"clau/valor %d, « %s », dins l’element d’adreça « %s »"
+"Error al moment del desencodatge de la clau o de la valor dins lo couple "
+"clau/valor %d, « %s », dins l'element d'adreça « %s »"
#: gio/gdbusaddress.c:589
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Error in address '%s' - the unix transport requires exactly one of the "
+#| "keys 'path' or 'abstract' to be set"
msgid ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
"“path” or “abstract” to be set"
msgstr ""
-"Error dins l’adreça « %s » — lo transpòrt Unix requerís que siá exactament "
+"Error dins l'adreça « %s » — lo transpòrt Unix requerís que siá exactement "
"definida una de las claus « path » o « abstract »"
#: gio/gdbusaddress.c:625
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error in address '%s' - the host attribute is missing or malformed"
msgid "Error in address “%s” — the host attribute is missing or malformed"
msgstr ""
-"Error dins l’adreça « %s » — l’atribut de l’òste es mancant o malformat"
+"Error dins l'adreça « %s » — l'atribut de l'òste es mancant o mal format"
#: gio/gdbusaddress.c:639
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error in address '%s' - the port attribute is missing or malformed"
msgid "Error in address “%s” — the port attribute is missing or malformed"
-msgstr "Error dins l’adreça « %s » — l’atribut del pòrt es mancant o malformat"
+msgstr ""
+"Error dins l'adreça « %s » — l'atribut del pòrt es mancant o mal format"
#: gio/gdbusaddress.c:653
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Error in address '%s' - the noncefile attribute is missing or malformed"
msgid "Error in address “%s” — the noncefile attribute is missing or malformed"
msgstr ""
-"Error dins l’adreça « %s » — l’atribut del fichièr amb denominacion unica es "
-"mancant o malformat"
+"Error dins l'adreça « %s » — l'atribut del fichièr de denominacion unica es "
+"mancant o mal format"
#: gio/gdbusaddress.c:674
msgid "Error auto-launching: "
msgstr "Error d'aviada automatica : "
#: gio/gdbusaddress.c:727
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error opening nonce file '%s': %s"
msgid "Error opening nonce file “%s”: %s"
msgstr ""
-"Error al moment de la dobertura del fichièr amb denominacion unica « %s » : "
-"%s"
+"Error al moment de la dobertura del fichièr de denominacion unica « %s » : %s"
#: gio/gdbusaddress.c:746
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error reading from nonce file '%s': %s"
msgid "Error reading from nonce file “%s”: %s"
-msgstr "Error de lectura del fichièr amb denominacion unica « %s » : %s"
+msgstr "Error de lectura del fichièr de denominacion unica « %s » : %s"
#: gio/gdbusaddress.c:755
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d"
msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d"
msgstr ""
-"Error de lectura del fichièr amb denominacion unica « %s », 16 octets "
+"Error de lectura del fichièr de denominacion unica « %s », 16 octets "
"esperats, %d recebuts"
#: gio/gdbusaddress.c:773
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error writing contents of nonce file '%s' to stream:"
msgid "Error writing contents of nonce file “%s” to stream:"
msgstr ""
-"Error d’escritura del contengut del fichièr amb denominacion unica « %s » "
-"sul flux :"
+"Error d'escritura del contengut del fichièr a numerotacion unica « %s » sul "
+"flux :"
#: gio/gdbusaddress.c:988
msgid "The given address is empty"
@@ -535,7 +564,8 @@ msgid "Cannot autolaunch D-Bus without X11 $DISPLAY"
msgstr "Impossible d'aviar automaticament D-Bus sens $DISPLAY X11"
#: gio/gdbusaddress.c:1157
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error spawning command line '%s': "
msgid "Error spawning command line “%s”: "
msgstr "Error al moment de la generacion de la linha de comanda « %s » : "
@@ -547,13 +577,16 @@ msgstr ""
"aqueste sistèma operatiu)"
#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7241
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment "
+#| "variable - unknown value '%s'"
msgid ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
"— unknown value “%s”"
msgstr ""
-"Impossible de determinar l’adreça del bus a partir de la variabla "
-"d’environament DBUS_STARTER_BUS_TYPE — valor desconeguda « %s »"
+"Impossible de determinar l'adreça del bus a partir de la variabla "
+"d'environament DBUS_STARTER_BUS_TYPE — valor desconeguda « %s »"
#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7250
msgid ""
@@ -597,10 +630,11 @@ msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
msgstr "Anullat via GDBusAuthObserver::authorize-authenticated-peer"
#: gio/gdbusauthmechanismsha1.c:298
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error when getting information for directory '%s': %s"
msgid "Error when getting information for directory “%s”: %s"
msgstr ""
-"Error al moment de la recuperacion d’informacion sul repertòri « %s » : %s"
+"Error al moment de la recuperacion d'informacion sul repertòri « %s » : %s"
#: gio/gdbusauthmechanismsha1.c:313
#, fuzzy, c-format
@@ -628,7 +662,8 @@ msgid "Operation not supported"
msgstr "Operacion pas presa en carga"
#: gio/gdbusauthmechanismsha1.c:402
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error opening keyring '%s' for reading: "
msgid "Error opening keyring “%s” for reading: "
msgstr ""
"Error al moment de la dobertura del trossèl de claus « %s » en lectura : "
@@ -672,30 +707,35 @@ msgstr ""
"claus de « %s »"
#: gio/gdbusauthmechanismsha1.c:523
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error creating lock file '%s': %s"
msgid "Error creating lock file “%s”: %s"
msgstr "Error al moment de la creacion del fichièr verrolh « %s » : %s"
#: gio/gdbusauthmechanismsha1.c:587
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error deleting stale lock file '%s': %s"
msgid "Error deleting stale lock file “%s”: %s"
msgstr ""
-"Error al moment de la destruccion de l’ancian fichièr verrolh « %s » : %s"
+"Error al moment de la destruccion de l'ancian fichièr verrolh « %s » : %s"
#: gio/gdbusauthmechanismsha1.c:626
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error closing (unlinked) lock file '%s': %s"
msgid "Error closing (unlinked) lock file “%s”: %s"
msgstr ""
-"Error al moment de la tampadura del fichièr verrolh (pas ligat) « %s » : %s"
+"Error al moment de la tampadura del fichièr verrolh (non ligat) « %s » : %s"
#: gio/gdbusauthmechanismsha1.c:637
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error unlinking lock file '%s': %s"
msgid "Error unlinking lock file “%s”: %s"
msgstr ""
"Error al moment de la supression del ligam amb lo fichièr verrolh « %s » : %s"
#: gio/gdbusauthmechanismsha1.c:714
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error opening keyring '%s' for writing: "
msgid "Error opening keyring “%s” for writing: "
msgstr ""
"Error al moment de la dobertura del trossèl de claus « %s » en escritura : "
@@ -732,22 +772,19 @@ msgstr ""
"l'emplaçament %s"
#: gio/gdbusconnection.c:4328
-#, fuzzy, c-format
-#| msgid "No such property '%s'"
+#, c-format
msgid "No such property “%s”"
msgstr "La proprietat « %s » existís pas"
#: gio/gdbusconnection.c:4340
-#, fuzzy, c-format
-#| msgid "Property '%s' is not readable"
+#, c-format
msgid "Property “%s” is not readable"
-msgstr "La proprietat « %s » pòt pas èsser legida"
+msgstr "La proprietat « %s » se pòt pas legir"
#: gio/gdbusconnection.c:4351
-#, fuzzy, c-format
-#| msgid "Property '%s' is not writable"
+#, c-format
msgid "Property “%s” is not writable"
-msgstr "La proprietat « %s » pòt pas èsser escrita"
+msgstr "La proprietat « %s » se pòt pas escriure"
#: gio/gdbusconnection.c:4371
#, fuzzy, c-format
@@ -771,7 +808,8 @@ msgid "No such interface “%s” on object at path %s"
msgstr "L'interfàcia « %s » existís pas per l'objècte a l'emplaçament %s"
#: gio/gdbusconnection.c:5000
-#, c-format
+#, fuzzy, c-format
+#| msgid "No such method '%s'"
msgid "No such method “%s”"
msgstr "Lo metòde « %s » existís pas"
@@ -797,12 +835,14 @@ msgid "Unable to set property %s.%s"
msgstr "Impossible de definir la proprietat %s.%s"
#: gio/gdbusconnection.c:5690
-#, c-format
+#, fuzzy, c-format
+#| msgid "Method '%s' returned type '%s', but expected '%s'"
msgid "Method “%s” returned type “%s”, but expected “%s”"
msgstr "Lo metòde « %s » a renviat lo tipe « %s », mas « %s » èra esperat"
#: gio/gdbusconnection.c:6792
-#, c-format
+#, fuzzy, c-format
+#| msgid "Method '%s' on interface '%s' with signature '%s' does not exist"
msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
msgstr ""
"Lo metòde « %s » sus l'interfàcia « %s » amb la signatura « %s » existís pas"
@@ -856,7 +896,8 @@ msgstr[0] "Lectura de %lu octet demandada, mas solament %lu recebut(s)"
msgstr[1] "Lectura de %lu octets demandada, mas solament %lu recebut(s)"
#: gio/gdbusmessage.c:1391
-#, c-format
+#, fuzzy, c-format
+#| msgid "Expected NUL byte after the string '%s' but found byte %d"
msgid "Expected NUL byte after the string “%s” but found byte %d"
msgstr ""
"Octet 00 (NUL) esperat a la fin de la cadena « %s » mas un octet %d es estat "
@@ -927,7 +968,10 @@ msgstr ""
"D-Bus"
#: gio/gdbusmessage.c:1936
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Error deserializing GVariant with type string '%s' from the D-Bus wire "
+#| "format"
msgid ""
"Error deserializing GVariant with type string “%s” from the D-Bus wire format"
msgstr ""
@@ -956,7 +1000,8 @@ msgid "Signature header found but is not of type signature"
msgstr ""
#: gio/gdbusmessage.c:2200
-#, c-format
+#, fuzzy, c-format
+#| msgid "Signature header with signature '%s' found but message body is empty"
msgid "Signature header with signature “%s” found but message body is empty"
msgstr ""
"Entèsta de signatura trobat amb la signatura « %s », mas lo còs del messatge "
@@ -985,7 +1030,9 @@ msgid "Cannot deserialize message: "
msgstr "Impossible de deserializar lo messatge : "
#: gio/gdbusmessage.c:2601
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Error serializing GVariant with type string '%s' to the D-Bus wire format"
msgid ""
"Error serializing GVariant with type string “%s” to the D-Bus wire format"
msgstr ""
@@ -1098,10 +1145,11 @@ msgstr ""
"creacion d'un servidor"
#: gio/gdbusserver.c:938
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error writing nonce file at '%s': %s"
msgid "Error writing nonce file at “%s”: %s"
msgstr ""
-"Error al moment de l’escritura del fichièr amb denominacion unica a « %s » : "
+"Error al moment de l'escritura del fichièr de denominacion unica a « %s » : "
"%s"
#: gio/gdbusserver.c:1113
@@ -1111,9 +1159,10 @@ msgid "The string “%s” is not a valid D-Bus GUID"
msgstr "La cadena « %s » es pas un GUID valid de D-Bus"
#: gio/gdbusserver.c:1153
-#, c-format
+#, fuzzy, c-format
+#| msgid "Cannot listen on unsupported transport '%s'"
msgid "Cannot listen on unsupported transport “%s”"
-msgstr "Impossible d’escotar sul transpòrt « %s » pas pres en carga"
+msgstr "Impossible d'escotar sul transpòrt « %s » pas pres en carga"
#: gio/gdbus-tool.c:111
#, fuzzy, c-format
@@ -1200,21 +1249,26 @@ msgid "Multiple connection endpoints specified"
msgstr "Mantun punt terminals de connexion definits"
#: gio/gdbus-tool.c:522
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: According to introspection data, interface '%s' does not exist\n"
msgid ""
"Warning: According to introspection data, interface “%s” does not exist\n"
msgstr ""
-"Avertiment : segon las donadas de l’examèn intèrne, l’interfàcia « %s » "
+"Avertiment : segon las donadas de l'examèn intèrne, l'interfàcia « %s » "
"existís pas\n"
#: gio/gdbus-tool.c:531
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "Warning: According to introspection data, method '%s' does not exist on "
+#| "interface '%s'\n"
msgid ""
"Warning: According to introspection data, method “%s” does not exist on "
"interface “%s”\n"
msgstr ""
-"Avertiment : segon las donadas de l’examèn intèrne, lo metòde « %s » existís "
-"pas sus l’interfàcia « %s »\n"
+"Avertiment : segon las donadas de l'examèn intèrne, lo metòde « %s » existís "
+"pas sus l'interfàcia « %s »\n"
#: gio/gdbus-tool.c:593
msgid "Optional destination for signal (unique name)"
@@ -1248,13 +1302,16 @@ msgid "Error: Object path is not specified\n"
msgstr "Error : lo camin per l'objècte es pas precisat\n"
#: gio/gdbus-tool.c:765
+#, fuzzy
+#| msgid "Error: Method name is not specified\n"
msgid "Error: Signal name is not specified\n"
-msgstr "Error : lo nom del senhal es pas definit\n"
+msgstr "Error : lo nom del metòde es pas definit\n"
#: gio/gdbus-tool.c:779
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error: Method name '%s' is invalid\n"
msgid "Error: Signal name “%s” is invalid\n"
-msgstr "Error : lo nom de senhal « %s » es pas valid\n"
+msgstr "Error : lo nom de metòde « %s » es pas valid\n"
#: gio/gdbus-tool.c:791
#, c-format
@@ -1311,14 +1368,16 @@ msgid "Error: Method name is not specified\n"
msgstr "Error : lo nom del metòde es pas definit\n"
#: gio/gdbus-tool.c:1086
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error: Method name '%s' is invalid\n"
msgid "Error: Method name “%s” is invalid\n"
msgstr "Error : lo nom de metòde « %s » es pas valid\n"
#: gio/gdbus-tool.c:1164
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error parsing parameter %d of type '%s': %s\n"
msgid "Error parsing parameter %d of type “%s”: %s\n"
-msgstr "Error d’analisi del paramètre %d de tipe « %s » : %s\n"
+msgstr "Error d'analisi del paramètre %d de tipe « %s » : %s\n"
#: gio/gdbus-tool.c:1190
#, c-format
@@ -1384,12 +1443,16 @@ msgid "Wait for a bus name to appear."
msgstr ""
#: gio/gdbus-tool.c:2321
+#, fuzzy
+#| msgid "Error: object path not specified.\n"
msgid "Error: A service to activate for must be specified.\n"
-msgstr "Error : un servici d'activar deu èsser indicat.\n"
+msgstr "Error : lo camin per l'objècte es pas precisat.\n"
#: gio/gdbus-tool.c:2326
+#, fuzzy
+#| msgid "Error: object path not specified.\n"
msgid "Error: A service to wait for must be specified.\n"
-msgstr "Error : un servici d'esperar deu èsser indicat.\n"
+msgstr "Error : lo camin per l'objècte es pas precisat.\n"
#: gio/gdbus-tool.c:2331
#, fuzzy
@@ -1398,9 +1461,10 @@ msgid "Error: Too many arguments.\n"
msgstr "Tròp d'arguments"
#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error: %s is not a valid bus name\n"
msgid "Error: %s is not a valid well-known bus name.\n"
-msgstr "Error : %s es pas un nom de bus plan conegut valid\n"
+msgstr "Error : %s es pas un nom de bus valid\n"
#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932
msgid "Unnamed"
@@ -1419,14 +1483,16 @@ msgid "Unable to find terminal required for application"
msgstr "Impossible de trobar lo terminal requesit per l'aplicacion"
#: gio/gdesktopappinfo.c:3452
-#, c-format
+#, fuzzy, c-format
+#| msgid "Can't create user application configuration folder %s: %s"
msgid "Can’t create user application configuration folder %s: %s"
msgstr ""
-"Impossible de crear lo dorsièr de configuracion utilizaire d’aplicacion %s : "
+"Impossible de crear lo dorsièr de configuracion utilizaire d'aplicacion %s : "
"%s"
#: gio/gdesktopappinfo.c:3456
-#, c-format
+#, fuzzy, c-format
+#| msgid "Can't create user MIME configuration folder %s: %s"
msgid "Can’t create user MIME configuration folder %s: %s"
msgstr ""
"Impossible de crear lo dorsièr de configuracion utilizaire MIME %s : %s"
@@ -1436,7 +1502,8 @@ msgid "Application information lacks an identifier"
msgstr "Las informacions de l'aplicacion compòrtan pas d'identificant"
#: gio/gdesktopappinfo.c:3958
-#, c-format
+#, fuzzy, c-format
+#| msgid "Can't create user desktop file %s"
msgid "Can’t create user desktop file %s"
msgstr "Impossible de crear lo fichièr .desktop utilizaire %s"
@@ -1446,6 +1513,8 @@ msgid "Custom definition for %s"
msgstr "Definicion personnalisée per %s"
#: gio/gdrive.c:417
+#, fuzzy
+#| msgid "drive doesn't implement eject"
msgid "drive doesn’t implement eject"
msgstr "lo lector implementa pas l'ejeccion (« eject »)"
@@ -1453,20 +1522,28 @@ msgstr "lo lector implementa pas l'ejeccion (« eject »)"
#. * message for drive objects that
#. * don't implement any of eject or eject_with_operation.
#: gio/gdrive.c:495
+#, fuzzy
+#| msgid "drive doesn't implement eject or eject_with_operation"
msgid "drive doesn’t implement eject or eject_with_operation"
msgstr ""
"lo lector implementa pas l'ejeccion combinada o pas (« eject » o « "
"eject_with_operation »)"
#: gio/gdrive.c:571
+#, fuzzy
+#| msgid "drive doesn't implement polling for media"
msgid "drive doesn’t implement polling for media"
msgstr "lo lector implementa pas l'escrutacion del mèdia (« polling »)"
#: gio/gdrive.c:778
+#, fuzzy
+#| msgid "drive doesn't implement start"
msgid "drive doesn’t implement start"
msgstr "lo lector implementa pas l'aviada (« start »)"
#: gio/gdrive.c:880
+#, fuzzy
+#| msgid "drive doesn't implement stop"
msgid "drive doesn’t implement stop"
msgstr "lo lector implementa pas l'arrèst (« stop »)"
@@ -1518,20 +1595,26 @@ msgid "Containing mount does not exist"
msgstr "Lo punt de montatge contenidor existís pas"
#: gio/gfile.c:2608 gio/glocalfile.c:2472
+#, fuzzy
+#| msgid "Can't copy over directory"
msgid "Can’t copy over directory"
-msgstr "Impossible d’espotir un repertòri"
+msgstr "Impossible d'espotir un repertòri"
#: gio/gfile.c:2668
+#, fuzzy
+#| msgid "Can't copy directory over directory"
msgid "Can’t copy directory over directory"
-msgstr "Impossible d’espotir un repertòri per un autre repertòri"
+msgstr "Impossible d'espotir un repertòri per un autre repertòri"
#: gio/gfile.c:2676
msgid "Target file exists"
msgstr "Lo fichièr cibla existís"
#: gio/gfile.c:2695
+#, fuzzy
+#| msgid "Can't recursively copy directory"
msgid "Can’t recursively copy directory"
-msgstr "Impossible de copiar recursivament un repertòri"
+msgstr "Impossible de copier recursivament un repertòri"
# http://en.wikipedia.org/wiki/Splice_(system_call)
#: gio/gfile.c:2996
@@ -1558,6 +1641,8 @@ msgid "Copy (reflink/clone) is not supported or didn’t work"
msgstr "La còpia (reflink/clone) es pas presa en carga o a pas foncionat"
#: gio/gfile.c:3226
+#, fuzzy
+#| msgid "Can't copy special file"
msgid "Can’t copy special file"
msgstr "Impossible de copiar lo fichièr especial"
@@ -1565,7 +1650,7 @@ msgstr "Impossible de copiar lo fichièr especial"
msgid "Invalid symlink value given"
msgstr "Valor de ligam simbolic donada invalida"
-#: gio/gfile.c:4045 glib/gfileutils.c:2362
+#: gio/gfile.c:4045 glib/gfileutils.c:2354
msgid "Symbolic links not supported"
msgstr "Ligams simbolics pas preses en carga"
@@ -1574,7 +1659,8 @@ msgid "Trash not supported"
msgstr "L'escobilhièr es pas presa en carga"
#: gio/gfile.c:4325
-#, c-format
+#, fuzzy, c-format
+#| msgid "File names cannot contain '%c'"
msgid "File names cannot contain “%c”"
msgstr "Los noms de fichièrs pòdon pas comportar de « %c »"
@@ -1602,7 +1688,8 @@ msgid "File enumerator is already closed"
msgstr "L'enumerador de fichièrs es ja tampat"
#: gio/gfileicon.c:250
-#, c-format
+#, fuzzy, c-format
+#| msgid "Can't handle version %d of GFileIcon encoding"
msgid "Can’t handle version %d of GFileIcon encoding"
msgstr "Impossible de gerir la version %d de l'encodatge de GFileIcon"
@@ -1613,6 +1700,8 @@ msgstr "Donadas d'entrada incorrèctas per GFileIcon"
#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394
#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164
#: gio/gfileoutputstream.c:497
+#, fuzzy
+#| msgid "Stream doesn't support query_info"
msgid "Stream doesn’t support query_info"
msgstr "Lo flux pren pas en carga query_info"
@@ -1716,9 +1805,10 @@ msgid "Address has bits set beyond prefix length"
msgstr "L'adreça possedís de bits definits al delà de la longor del prefix"
#: gio/ginetaddressmask.c:300
-#, c-format
+#, fuzzy, c-format
+#| msgid "Could not parse '%s' as IP address mask"
msgid "Could not parse “%s” as IP address mask"
-msgstr "Impossible d’analisar « %s » coma masqueta d’adreça IP"
+msgstr "Impossible d'analisar « %s » coma masque d'adreça IP"
#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220
#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220
@@ -1754,8 +1844,10 @@ msgid "Keep with file when moved"
msgstr "Conservar amb lo fichièr al moment del desplaçament"
#: gio/gio-tool.c:205
+#, fuzzy
+#| msgid "'version' takes no arguments"
msgid "“version” takes no arguments"
-msgstr "« version » accèpta pas cap de paramètre"
+msgstr "« %s » accèpta pas cap de paramètre"
#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869
msgid "Usage:"
@@ -1782,8 +1874,12 @@ msgid "Show information about locations"
msgstr "Afichar l'informacion sus las localizacions"
#: gio/gio-tool.c:232
+#, fuzzy
+#| msgid "List static actions for an application (from .desktop file)"
msgid "Launch an application from a desktop file"
-msgstr "Aviar una aplicacion a partir d’un fichièr desktop"
+msgstr ""
+"Afichar la lista de las accions estaticas d'una aplicacion (a partir del "
+"fichièr .desktop)"
#: gio/gio-tool.c:233
msgid "List the contents of locations"
@@ -1843,8 +1939,10 @@ msgid "Use %s to get detailed help.\n"
msgstr "Utilizatz « %s » per obténer d'ajuda detalhada.\n"
#: gio/gio-tool-cat.c:87
+#, fuzzy
+#| msgid "Error writing to file: %s"
msgid "Error writing to stdout"
-msgstr "Error al moment de l’escritura cap a stdout"
+msgstr "Error al moment de l'escritura del fichièr : %s"
#. Translators: commandline placeholder
#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172
@@ -2027,6 +2125,13 @@ msgid "Show information about locations."
msgstr "Afichar d'informacions a prepaus dels emplaçaments."
#: gio/gio-tool-info.c:347
+#, fuzzy
+#| msgid ""
+#| "gio info is similar to the traditional ls utility, but using GIO\n"
+#| "locations instead of local files: for example, you can use something\n"
+#| "like smb://server/resource/file.txt as location. File attributes can\n"
+#| "be specified with their GIO name, e.g. standard::icon, or just by\n"
+#| "namespace, e.g. unix, or by '*', which matches all attributes"
msgid ""
"gio info is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -2034,7 +2139,7 @@ msgid ""
"be specified with their GIO name, e.g. standard::icon, or just by\n"
"namespace, e.g. unix, or by “*”, which matches all attributes"
msgstr ""
-"gio info fonciona coma l’utilitari tradicional ls, mas en\n"
+"gio info fonciona coma l'utilitari tradicional ls, mas en\n"
"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n"
"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt.\n"
"Los atributs de fichièrs pòdon èsser indicats per lor nom GIO (exemple :\n"
@@ -2054,7 +2159,7 @@ msgstr ""
#: gio/gio-tool-launch.c:77
msgid "No desktop file given"
-msgstr "Cap de fichièr de burèu pas indicat"
+msgstr "Cap de fichièr pas indicat"
#: gio/gio-tool-launch.c:85
#, fuzzy
@@ -2086,8 +2191,10 @@ msgid "Use a long listing format"
msgstr "Utilizar una mesa en forma de lista espandida"
#: gio/gio-tool-list.c:40
+#, fuzzy
+#| msgid "display name: %s\n"
msgid "Print display names"
-msgstr "Afichar los noms d’afichatge"
+msgstr "nom d'afichatge : %s\n"
#: gio/gio-tool-list.c:41
msgid "Print full URIs"
@@ -2138,12 +2245,14 @@ msgid "Must specify a single mimetype, and maybe a handler"
msgstr "Un seul tipe MIME deu èsser indicat, e potencialament un gestionari"
#: gio/gio-tool-mime.c:116
-#, c-format
+#, fuzzy, c-format
+#| msgid "No default applications for '%s'\n"
msgid "No default applications for “%s”\n"
-msgstr "Pas cap d'aplicacion per defaut per « %s »\n"
+msgstr "Pas d'aplicacions per defaut per « %s »\n"
#: gio/gio-tool-mime.c:122
-#, c-format
+#, fuzzy, c-format
+#| msgid "Default application for '%s': %s\n"
msgid "Default application for “%s”: %s\n"
msgstr "Aplicacion per defaut per « %s » : %s\n"
@@ -2296,16 +2405,19 @@ msgid "The numeric PIM when unlocking a VeraCrypt volume"
msgstr ""
#: gio/gio-tool-mount.c:75
+#, fuzzy
+#| msgctxt "GDateTime"
+#| msgid "PM"
msgid "PIM"
-msgstr "PIM"
+msgstr "PM"
#: gio/gio-tool-mount.c:76
msgid "Mount a TCRYPT hidden volume"
-msgstr ""
+msgstr "Montar un volume amagat TCRYPT"
#: gio/gio-tool-mount.c:77
msgid "Mount a TCRYPT system volume"
-msgstr ""
+msgstr "Montar un volume sistèma TCRYPT"
#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297
msgid "Anonymous access denied"
@@ -2421,8 +2533,10 @@ msgid "ETAG"
msgstr "ETAG"
#: gio/gio-tool-save.c:113
+#, fuzzy
+#| msgid "Error reading from handle: %s"
msgid "Error reading from standard input"
-msgstr "Error de lectura a partir de l’entrada estandarda"
+msgstr "Error de lectura a partir de l'identificador : %s"
#. Translators: The "etag" is a token allowing to verify whether a file has been modified
#: gio/gio-tool-save.c:139
@@ -2562,7 +2676,8 @@ msgid "Failed to locate “%s” in current directory"
msgstr "La localizacion de « %s » dins lo repertòri actual a fracassat"
#: gio/glib-compile-resources.c:290
-#, c-format
+#, fuzzy, c-format
+#| msgid "Unknown processing option \"%s\""
msgid "Unknown processing option “%s”"
msgstr "Opcion de tractament desconeguda « %s »"
@@ -2596,10 +2711,16 @@ msgid "Show program version and exit"
msgstr ""
#: gio/glib-compile-resources.c:738
+#, fuzzy
+#| msgid "name of the output file"
msgid "Name of the output file"
-msgstr "Nom del fichièr de sortida"
+msgstr "nom del fichièr de sortida"
#: gio/glib-compile-resources.c:739
+#, fuzzy
+#| msgid ""
+#| "The directories where files are to be read from (default to current "
+#| "directory)"
msgid ""
"The directories to load files referenced in FILE from (default: current "
"directory)"
@@ -2636,18 +2757,24 @@ msgid "Generate dependency list"
msgstr "Generar la lista de las dependéncias"
#: gio/glib-compile-resources.c:744
+#, fuzzy
+#| msgid "name of the dependency file to generate"
msgid "Name of the dependency file to generate"
-msgstr "Nom del fichièr de dependéncias de generar"
+msgstr "nom del fichièr de las dependéncias de generar"
#: gio/glib-compile-resources.c:745
msgid "Include phony targets in the generated dependency file"
msgstr ""
#: gio/glib-compile-resources.c:746
+#, fuzzy
+#| msgid "Don't automatically create and register resource"
msgid "Don’t automatically create and register resource"
msgstr "Crear pas e enregistrar automaticament la ressorsa"
#: gio/glib-compile-resources.c:747
+#, fuzzy
+#| msgid "Don't export functions; declare them G_GNUC_INTERNAL"
msgid "Don’t export functions; declare them G_GNUC_INTERNAL"
msgstr "Exportar pas las foncions ; las declarar G_GNUC_INTERNAL"
@@ -2682,19 +2809,22 @@ msgid "nick must be a minimum of 2 characters"
msgstr ""
#: gio/glib-compile-schemas.c:103
-#, c-format
+#, fuzzy, c-format
+#| msgid "Invalid symlink value given"
msgid "Invalid numeric value"
-msgstr "Valor numeric invalida"
+msgstr "Valor de ligam simbolic donada invalida"
#: gio/glib-compile-schemas.c:111
-#, c-format
+#, fuzzy, c-format
+#| msgid "<%s id='%s'> already specified"
msgid "<value nick='%s'/> already specified"
-msgstr "<value nick='%s'/>'> es ja definit"
+msgstr "<%s id='%s'> es ja definit"
#: gio/glib-compile-schemas.c:119
-#, c-format
+#, fuzzy, c-format
+#| msgid "<key name='%s'> already specified"
msgid "value='%s' already specified"
-msgstr "value='%s' es ja estat definit"
+msgstr "<key name='%s'> a ja été definit"
#: gio/glib-compile-schemas.c:133
#, c-format
@@ -2707,9 +2837,10 @@ msgid "<%s> must contain at least one <value>"
msgstr ""
#: gio/glib-compile-schemas.c:314
-#, c-format
+#, fuzzy, c-format
+#| msgid "No connection endpoint specified"
msgid "<%s> is not contained in the specified range"
-msgstr "<%s> es pas contengut dins l’interval definit"
+msgstr "Cap de punt terminal de connexion pas definit"
#: gio/glib-compile-schemas.c:326
#, c-format
@@ -2727,8 +2858,10 @@ msgid "<%s> contains a string not in <choices>"
msgstr ""
#: gio/glib-compile-schemas.c:372
+#, fuzzy
+#| msgid "<key name='%s'> already specified"
msgid "<range/> already specified for this key"
-msgstr "<range/> es ja estat definit per aquesta clau"
+msgstr "<key name='%s'> a ja été definit"
#: gio/glib-compile-schemas.c:390
#, c-format
@@ -2767,8 +2900,10 @@ msgid ""
msgstr ""
#: gio/glib-compile-schemas.c:500
+#, fuzzy
+#| msgid "<child name='%s'> already specified"
msgid "<choices> already specified for this key"
-msgstr "<choices> es ja estat definit per aquesta clau"
+msgstr "<child name='%s'> es ja estat definit"
#: gio/glib-compile-schemas.c:512
#, c-format
@@ -2776,9 +2911,10 @@ msgid "<choices> not allowed for keys of type “%s”"
msgstr ""
#: gio/glib-compile-schemas.c:528
-#, c-format
+#, fuzzy, c-format
+#| msgid "<child name='%s'> already specified"
msgid "<choice value='%s'/> already given"
-msgstr "<choice value='%s'> es ja estat definit"
+msgstr "<child name='%s'> es ja estat definit"
#: gio/glib-compile-schemas.c:543
#, c-format
@@ -2786,8 +2922,10 @@ msgid "<choices> must contain at least one <choice>"
msgstr ""
#: gio/glib-compile-schemas.c:557
+#, fuzzy
+#| msgid "<child name='%s'> already specified"
msgid "<aliases> already specified for this key"
-msgstr "<aliases> es ja estat definit per aquesta clau"
+msgstr "<child name='%s'> es ja estat definit"
#: gio/glib-compile-schemas.c:561
msgid ""
@@ -2808,9 +2946,10 @@ msgid "<alias value='%s'/> given when <choice value='%s'/> was already given"
msgstr ""
#: gio/glib-compile-schemas.c:594
-#, c-format
+#, fuzzy, c-format
+#| msgid "<%s id='%s'> already specified"
msgid "<alias value='%s'/> already specified"
-msgstr "<alias value='%s'/> es ja definit"
+msgstr "<%s id='%s'> es ja definit"
#: gio/glib-compile-schemas.c:604
#, c-format
@@ -2828,39 +2967,48 @@ msgid "<aliases> must contain at least one <alias>"
msgstr ""
#: gio/glib-compile-schemas.c:797
+#, fuzzy
+#| msgid "empty names are not permitted"
msgid "Empty names are not permitted"
-msgstr "Los noms voids son pas autorizats"
+msgstr "los noms voids son pas autorizats"
#: gio/glib-compile-schemas.c:807
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid name '%s': names must begin with a lowercase letter"
msgid "Invalid name “%s”: names must begin with a lowercase letter"
-msgstr "Nom « %s » invalid : los noms devon començar per una letra minuscula"
+msgstr "nom « %s » invalid : los noms devon començar per una letra minuscula"
#: gio/glib-compile-schemas.c:819
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "invalid name '%s': invalid character '%c'; only lowercase letters, "
+#| "numbers and hyphen ('-') are permitted."
msgid ""
"Invalid name “%s”: invalid character “%c”; only lowercase letters, numbers "
"and hyphen (“-”) are permitted"
msgstr ""
"nom « %s » invalid : caractèr « %c » invalid ; sols las minusculas, los "
-"nombres e lo jonhent (« - ») son autorizats"
+"nombres e lo jonhent (« - ») son autorizats."
#: gio/glib-compile-schemas.c:828
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid name '%s': two successive hyphens ('--') are not permitted."
msgid "Invalid name “%s”: two successive hyphens (“--”) are not permitted"
msgstr ""
-"nom « %s » invalid : dos jonhents successius (« -- ») son pas autorizats"
+"nom « %s » invalid : dos jonhents successius (« -- ») son pas autorizats."
#: gio/glib-compile-schemas.c:837
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid name '%s': the last character may not be a hyphen ('-')."
msgid "Invalid name “%s”: the last character may not be a hyphen (“-”)"
msgstr ""
-"Nom « %s » invalid : lo darrièr caractèr pòt pas èsser un jonhent (« - »)"
+"nom « %s » invalid : lo darrièr caractèr pòt pas èsser un jonhent (« - »)."
#: gio/glib-compile-schemas.c:845
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid name '%s': maximum length is 1024"
msgid "Invalid name “%s”: maximum length is 1024"
-msgstr "Nom « %s » invalid : la longor maximala es 1024"
+msgstr "nom « %s » invalid : la longor maximala es 1024"
#: gio/glib-compile-schemas.c:917
#, c-format
@@ -2886,12 +3034,15 @@ msgstr ""
"<override> per modificar la valor"
#: gio/glib-compile-schemas.c:983
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "exactly one of 'type', 'enum' or 'flags' must be specified as an "
+#| "attribute to <key>"
msgid ""
"Exactly one of “type”, “enum” or “flags” must be specified as an attribute "
"to <key>"
msgstr ""
-"<key> pòt pas recebre qu’un e un sol atribut demest « type », « enum » o « "
+"<key> pòt pas recebre qu'un e un sol atribut demest « tipe », « enum » o « "
"flags »"
#: gio/glib-compile-schemas.c:1002
@@ -2900,9 +3051,10 @@ msgid "<%s id='%s'> not (yet) defined."
msgstr "<%s id='%s'> pas (encara) definit."
#: gio/glib-compile-schemas.c:1017
-#, c-format
+#, fuzzy, c-format
+#| msgid "invalid GVariant type string '%s'"
msgid "Invalid GVariant type string “%s”"
-msgstr "Cadena de tipe GVariant « %s » invalida"
+msgstr "cadena de tipe GVariant « %s » invalida"
#: gio/glib-compile-schemas.c:1047
#, fuzzy
@@ -2911,9 +3063,10 @@ msgid "<override> given but schema isn’t extending anything"
msgstr "un <override> es donat mas son esquèma espandís pas res"
#: gio/glib-compile-schemas.c:1060
-#, c-format
+#, fuzzy, c-format
+#| msgid "no <key name='%s'> to override"
msgid "No <key name='%s'> to override"
-msgstr "Pas cap de <key name='%s'> de remplaçar"
+msgstr "pas cap de <key name='%s'> de redefinir"
#: gio/glib-compile-schemas.c:1068
#, c-format
@@ -2926,12 +3079,14 @@ msgid "<schema id='%s'> already specified"
msgstr "<schema id='%s'> ja definit"
#: gio/glib-compile-schemas.c:1153
-#, c-format
+#, fuzzy, c-format
+#| msgid "<schema id='%s'> extends not yet existing schema '%s'"
msgid "<schema id='%s'> extends not yet existing schema “%s”"
msgstr "<schema id='%s'> espandís l'esquèma « %s » qu'existís pas encara"
#: gio/glib-compile-schemas.c:1169
-#, c-format
+#, fuzzy, c-format
+#| msgid "<schema id='%s'> is list of not yet existing schema '%s'"
msgid "<schema id='%s'> is list of not yet existing schema “%s”"
msgstr ""
"<schema id='%s'> es una lista de l'esquèma « %s » qu'existís pas encara"
@@ -2943,9 +3098,10 @@ msgid "Cannot be a list of a schema with a path"
msgstr "Un esquèma amb un camin pòt pas conténer de lista"
#: gio/glib-compile-schemas.c:1187
-#, c-format
+#, fuzzy, c-format
+#| msgid "Can not extend a schema with a path"
msgid "Cannot extend a schema with a path"
-msgstr "Impossible d’espandir un esquèma amb un camin"
+msgstr "Impossible d'espandir un esquèma amb un camin"
#: gio/glib-compile-schemas.c:1197
#, c-format
@@ -2955,13 +3111,16 @@ msgstr ""
"<schema id='%s'> es una lista ; espandís <schema id='%s'> qu'es pas una lista"
#: gio/glib-compile-schemas.c:1207
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "<schema id='%s' list-of='%s'> extends <schema id='%s' list-of='%s'> but "
+#| "'%s' does not extend '%s'"
msgid ""
"<schema id='%s' list-of='%s'> extends <schema id='%s' list-of='%s'> but “%s” "
"does not extend “%s”"
msgstr ""
"<schema id='%s' list-of='%s'> espandís <schema id='%s' list-of='%s'> mas « "
-"%s » espandís pas « %s »"
+"%s » n'étend pas « %s »"
#: gio/glib-compile-schemas.c:1224
#, fuzzy, c-format
@@ -3002,9 +3161,10 @@ msgid "Element <default> is required in <key>"
msgstr ""
#: gio/glib-compile-schemas.c:1626
-#, c-format
+#, fuzzy, c-format
+#| msgid "text may not appear inside <%s>"
msgid "Text may not appear inside <%s>"
-msgstr "Es possible que lo tèxte aparesca pas a l'interior de <%s>"
+msgstr "<%s> pòt pas conténer de tèxte"
#: gio/glib-compile-schemas.c:1694
#, c-format
@@ -3135,8 +3295,10 @@ msgstr ""
"redefinicion « %s » es pas dins la lista de las causida validas"
#: gio/glib-compile-schemas.c:2173
+#, fuzzy
+#| msgid "where to store the gschemas.compiled file"
msgid "Where to store the gschemas.compiled file"
-msgstr "Lòc ont enregistrar lo fichièr gschemas.compiled"
+msgstr "endreit ont enregistrar lo fichièr gschemas.compiled"
#: gio/glib-compile-schemas.c:2174
msgid "Abort on any errors in schemas"
@@ -3161,8 +3323,10 @@ msgstr ""
"e lo fichièr cache es nomenat gschemas.compiled."
#: gio/glib-compile-schemas.c:2226
+#, fuzzy
+#| msgid "You should give exactly one directory name\n"
msgid "You should give exactly one directory name"
-msgstr "Devètz indicar exactament un nom de repertòri"
+msgstr "Vos cal indicar un e un sol nom de repertòri\n"
#: gio/glib-compile-schemas.c:2269
#, fuzzy
@@ -3171,10 +3335,8 @@ msgid "No schema files found: doing nothing."
msgstr "Cap de fichièr esquèma pas trobat : "
#: gio/glib-compile-schemas.c:2271
-#, fuzzy
-#| msgid "removed existing output file.\n"
msgid "No schema files found: removed existing output file."
-msgstr "fichièr de sortida existent suprimit.\n"
+msgstr ""
#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436
#, c-format
@@ -3197,6 +3359,8 @@ msgid "Containing mount for file %s not found"
msgstr "Lo punt de montatge contenidor pel fichièr %s es introbable"
#: gio/glocalfile.c:1144
+#, fuzzy
+#| msgid "Can't rename root directory"
msgid "Can’t rename root directory"
msgstr "Impossible de renomenar lo repertòri raiç"
@@ -3206,8 +3370,10 @@ msgid "Error renaming file %s: %s"
msgstr "Error de renomenatge del fichièr %s : %s"
#: gio/glocalfile.c:1169
+#, fuzzy
+#| msgid "Can't rename file, filename already exists"
msgid "Can’t rename file, filename already exists"
-msgstr "Impossible de renomenar lo fichièr, lo nom de fichièr existís ja"
+msgstr "Impossible de renomenar lo fichièr perque aqueste nom es ja utilizat"
#: gio/glocalfile.c:1182 gio/glocalfile.c:2366 gio/glocalfile.c:2394
#: gio/glocalfile.c:2533 gio/glocalfileoutputstream.c:656
@@ -3297,12 +3463,14 @@ msgid "Error moving file %s: %s"
msgstr "Error al moment del desplaçament del fichièr %s : %s"
#: gio/glocalfile.c:2467
+#, fuzzy
+#| msgid "Can't move directory over directory"
msgid "Can’t move directory over directory"
msgstr "Impossible de desplaçar un repertòri per dessús un autre"
-#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1108
-#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137
-#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168
+#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1079
+#: gio/glocalfileoutputstream.c:1093 gio/glocalfileoutputstream.c:1108
+#: gio/glocalfileoutputstream.c:1125 gio/glocalfileoutputstream.c:1139
msgid "Backup file creation failed"
msgstr "La creacion del fichièr de salvament a fracassat"
@@ -3333,20 +3501,21 @@ msgid "Invalid extended attribute name"
msgstr "Nom d'atribut espandit invalid"
#: gio/glocalfileinfo.c:821
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error setting extended attribute '%s': %s"
msgid "Error setting extended attribute “%s”: %s"
-msgstr "Error al moment de la definicion de l’atribut espandit « %s » : %s"
+msgstr "Error al moment de la definicion de l'atribut espandit « %s » : %s"
#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
msgstr " (encodatge invalid)"
#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943
-#: gio/glocalfileoutputstream.c:995
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error when getting information for file '%s': %s"
msgid "Error when getting information for file “%s”: %s"
msgstr ""
-"Error al moment de l’obtencion de las informacions del fichièr « %s » : %s"
+"Error al moment de l'obtencion de las informacions del fichièr « %s » : %s"
#: gio/glocalfileinfo.c:2134
#, c-format
@@ -3428,11 +3597,11 @@ msgid "File “%s” cannot be opened: Windows Error %lu"
msgstr ""
#: gio/glocalfileinfo.c:2589
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error setting modification or access time: %s"
msgid "Error setting modification or access time for file “%s”: %lu"
msgstr ""
-"Error al moment de la definicion de l'ora de modificacion o d'accès pel "
-"fichièr « %s » : %lu"
+"Error al moment de la definicion de l'ora de modificacion o d'accès : %s"
#: gio/glocalfileinfo.c:2690
#, c-format
@@ -3470,7 +3639,7 @@ msgid "Error closing file: %s"
msgstr "Error al moment de la tampadura del fichièr : %s"
#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563
-#: gio/glocalfileoutputstream.c:1186
+#: gio/glocalfileoutputstream.c:1157
#, c-format
msgid "Error seeking in file: %s"
msgstr "Error de posicionament dins lo fichièr : %s"
@@ -3500,13 +3669,13 @@ msgstr "Error al moment de la creacion de la còpia de salvament : %s"
msgid "Error renaming temporary file: %s"
msgstr "Error al moment del cambiament de nom del fichièr temporari : %s"
-#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237
+#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1208
#, c-format
msgid "Error truncating file: %s"
msgstr "Error al moment de la troncadura del fichièr : %s"
#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907
-#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226
+#: gio/glocalfileoutputstream.c:1189 gio/gsubprocess.c:226
#, c-format
msgid "Error opening file “%s”: %s"
msgstr "Error al moment de la dobertura del fichièr « %s » : %s"
@@ -3519,11 +3688,11 @@ msgstr "Lo fichièr cibla es un repertòri"
msgid "Target file is not a regular file"
msgstr "Lo fichièr cibla es pas un fichièr estandard"
-#: gio/glocalfileoutputstream.c:1013
+#: gio/glocalfileoutputstream.c:984
msgid "The file was externally modified"
msgstr "Lo fichièr es estat modificat exteriorament"
-#: gio/glocalfileoutputstream.c:1202
+#: gio/glocalfileoutputstream.c:1173
#, c-format
msgid "Error removing old file: %s"
msgstr "Error a la supression de l'ancian fichièr : %s"
@@ -3568,6 +3737,8 @@ msgstr "Posicionament demandat aprèp la fin del flux"
#. * message for mount objects that
#. * don't implement unmount.
#: gio/gmount.c:399
+#, fuzzy
+#| msgid "mount doesn't implement \"unmount\""
msgid "mount doesn’t implement “unmount”"
msgstr "mount implementa pas lo desmontatge (« unmount »)"
@@ -3656,10 +3827,9 @@ msgid "Could not get network status: "
msgstr "Impossible d'obténer l'estatut de la ret : "
#: gio/gnetworkmonitornm.c:348
-#, fuzzy, c-format
-#| msgid "NetworkManager version too old"
+#, c-format
msgid "NetworkManager not running"
-msgstr "La version de NetworkManager es tròp anciana"
+msgstr "NetworkManager es pas aviat"
#: gio/gnetworkmonitornm.c:359
#, c-format
@@ -3688,13 +3858,16 @@ msgstr "Error de resolucion de « %s » : %s"
#. Translators: The placeholder is for a function name.
#: gio/gresolver.c:455 gio/gresolver.c:615
-#, c-format
+#, fuzzy, c-format
+#| msgid "Input stream doesn't implement read"
msgid "%s not implemented"
-msgstr "%s es pas implementat"
+msgstr "Lo flux en entrada implementa pas « read »"
#: gio/gresolver.c:984 gio/gresolver.c:1036
+#, fuzzy
+#| msgid "Invalid filename"
msgid "Invalid domain"
-msgstr "Domeni invalid"
+msgstr "Nom de fichièr invalid"
#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983
#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253
@@ -3718,6 +3891,8 @@ msgid "The resource at “%s” is not a directory"
msgstr "La ressorsa dins « %s » es pas un repertòri"
#: gio/gresourcefile.c:940
+#, fuzzy
+#| msgid "Input stream doesn't implement seek"
msgid "Input stream doesn’t implement seek"
msgstr "Lo flux en entrada implementa pas « seek » (lo posicionament)"
@@ -3858,8 +4033,7 @@ msgid " PATH A resource path\n"
msgstr " CAMIN Un camin de ressorsa\n"
#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906
-#, fuzzy, c-format
-#| msgid "No such schema '%s'\n"
+#, c-format
msgid "No such schema “%s”\n"
msgstr "L'esquèma « %s » existís pas\n"
@@ -4107,8 +4281,7 @@ msgid "Empty schema name given\n"
msgstr "Nom d'esquèma provesit void\n"
#: gio/gsettings-tool.c:919
-#, fuzzy, c-format
-#| msgid "No such key '%s'\n"
+#, c-format
msgid "No such key “%s”\n"
msgstr "La clau « %s » existís pas\n"
@@ -4198,12 +4371,14 @@ msgid "No support for source-specific multicast"
msgstr "Pas cap de presa en carga pel multicast especific a la font"
#: gio/gsocket.c:2534
+#, fuzzy
+#| msgid "Unsupported socket address"
msgid "Unsupported socket family"
-msgstr "Familha de connector ret pas presa en carga"
+msgstr "Adreça de connector ret pas presa en carga"
#: gio/gsocket.c:2559
msgid "source-specific not an IPv4 address"
-msgstr "source-specific es pas una adreça IPv4"
+msgstr ""
#: gio/gsocket.c:2583
#, c-format
@@ -4265,36 +4440,36 @@ msgstr "Error al moment de la tampadura del connector : %s"
msgid "Waiting for socket condition: %s"
msgstr "En espèra de l'estat del connector : %s"
-#: gio/gsocket.c:4806 gio/gsocket.c:4824 gio/gsocket.c:4837
+#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833
#, c-format
msgid "Unable to send message: %s"
msgstr "Impossible d'enviar lo messatge : %s"
-#: gio/gsocket.c:4807 gio/gsocket.c:4825 gio/gsocket.c:4838
+#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834
msgid "Message vectors too large"
msgstr ""
-#: gio/gsocket.c:4854 gio/gsocket.c:4856 gio/gsocket.c:5003 gio/gsocket.c:5088
-#: gio/gsocket.c:5266 gio/gsocket.c:5306 gio/gsocket.c:5308
+#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084
+#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304
#, c-format
msgid "Error sending message: %s"
msgstr "Error de mandadís de messatge : %s"
-#: gio/gsocket.c:5030
+#: gio/gsocket.c:5026
msgid "GSocketControlMessage not supported on Windows"
msgstr "GSocketControlMessage es pas pres en carga per Windows"
-#: gio/gsocket.c:5499 gio/gsocket.c:5575 gio/gsocket.c:5801
+#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797
#, c-format
msgid "Error receiving message: %s"
msgstr "Error al moment de la recepcion del messatge : %s"
-#: gio/gsocket.c:6074 gio/gsocket.c:6085 gio/gsocket.c:6131
+#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "Impossible de legir las donadas d'autentificacion del connector : %s"
-#: gio/gsocket.c:6140
+#: gio/gsocket.c:6136
msgid "g_socket_get_credentials not implemented for this OS"
msgstr ""
"g_socket_get_credentials es pas implementat sus aqueste sistèma operatiu"
@@ -4438,15 +4613,17 @@ msgid "No valid addresses were found"
msgstr "Cap d'adreça valida es pas estada trobada"
#: gio/gthreadedresolver.c:337
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error reverse-resolving '%s': %s"
msgid "Error reverse-resolving “%s”: %s"
msgstr "Error de resolucion invèrsa de « %s » : %s"
#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755
#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903
-#, c-format
+#, fuzzy, c-format
+#| msgid "No DNS record of the requested type for '%s'"
msgid "No DNS record of the requested type for “%s”"
-msgstr "Pas cap d'enregistrament DNS del tipe demandat per « %s »"
+msgstr "Cap d'enregistrament DNS del tipe pas demandat per « %s »"
#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858
#, fuzzy, c-format
@@ -4460,27 +4637,27 @@ msgstr "Impossible temporàriament de resòlvre « %s »"
msgid "Error resolving “%s”"
msgstr "Error de resolucion de « %s »"
-#: gio/gtlscertificate.c:299
+#: gio/gtlscertificate.c:298
msgid "No PEM-encoded private key found"
msgstr "Cap de clau privada pas encodada PEM trobada"
-#: gio/gtlscertificate.c:309
+#: gio/gtlscertificate.c:308
msgid "Cannot decrypt PEM-encoded private key"
msgstr "Impossible de deschifrar la clau privada encodada-PEM"
-#: gio/gtlscertificate.c:320
+#: gio/gtlscertificate.c:319
msgid "Could not parse PEM-encoded private key"
msgstr "Impossible d'analisar la clau privada encodada-PEM"
-#: gio/gtlscertificate.c:347
+#: gio/gtlscertificate.c:346
msgid "No PEM-encoded certificate found"
msgstr "Cap de certificat encodat-PEM pas trobat"
-#: gio/gtlscertificate.c:356
+#: gio/gtlscertificate.c:355
msgid "Could not parse PEM-encoded certificate"
msgstr "Impossible d'analisar lo certificat encodat-PEM"
-#: gio/gtlscertificate.c:711
+#: gio/gtlscertificate.c:710
msgid "This GTlsBackend does not support creating PKCS #11 certificates"
msgstr ""
@@ -4666,9 +4843,10 @@ msgid "Wrong args\n"
msgstr "Arguments incorrèctes\n"
#: glib/gbookmarkfile.c:768
-#, c-format
+#, fuzzy, c-format
+#| msgid "Unexpected attribute '%s' for element '%s'"
msgid "Unexpected attribute “%s” for element “%s”"
-msgstr "Atribut « %s » inesperat per l’element « %s »"
+msgstr "Atribut « %s » inesperat per l'element « %s »"
#: glib/gbookmarkfile.c:779 glib/gbookmarkfile.c:859 glib/gbookmarkfile.c:869
#: glib/gbookmarkfile.c:982
@@ -4679,15 +4857,17 @@ msgstr "L'atribut « %s » de l'element « %s » es introbable"
#: glib/gbookmarkfile.c:1191 glib/gbookmarkfile.c:1256
#: glib/gbookmarkfile.c:1320 glib/gbookmarkfile.c:1330
-#, c-format
+#, fuzzy, c-format
+#| msgid "Unexpected tag '%s', tag '%s' expected"
msgid "Unexpected tag “%s”, tag “%s” expected"
msgstr "Balisa « %s » inesperada. La balisa « %s » èra esperada"
#: glib/gbookmarkfile.c:1216 glib/gbookmarkfile.c:1230
#: glib/gbookmarkfile.c:1298 glib/gbookmarkfile.c:1344
-#, c-format
+#, fuzzy, c-format
+#| msgid "Unexpected tag '%s' inside '%s'"
msgid "Unexpected tag “%s” inside “%s”"
-msgstr "Balisa « %s » inesperada a l’interior de « %s »"
+msgstr "Balisa « %s » inesperada a l'interior de « %s »"
#: glib/gbookmarkfile.c:1624
#, c-format
@@ -4720,19 +4900,22 @@ msgid "No bookmark found for URI “%s”"
msgstr "Cap de signet pas trobat per l'URI « %s »"
#: glib/gbookmarkfile.c:2409
-#, c-format
+#, fuzzy, c-format
+#| msgid "No MIME type defined in the bookmark for URI '%s'"
msgid "No MIME type defined in the bookmark for URI “%s”"
-msgstr "Cap de tipe MIME pas definit dins lo signet per l’URI « %s »"
+msgstr "Cap de tipe MIME pas definit dins lo signet per l'URI « %s »"
#: glib/gbookmarkfile.c:2494
-#, c-format
+#, fuzzy, c-format
+#| msgid "No private flag has been defined in bookmark for URI '%s'"
msgid "No private flag has been defined in bookmark for URI “%s”"
-msgstr "Cap d'indicator privat es pas definit dins lo signet per l’URI « %s »"
+msgstr "Cap d'indicator privat es pas definit dins lo signet per l'URI « %s »"
#: glib/gbookmarkfile.c:3035
-#, c-format
+#, fuzzy, c-format
+#| msgid "No groups set in bookmark for URI '%s'"
msgid "No groups set in bookmark for URI “%s”"
-msgstr "Cap de grop es pas definit dins lo signet per l’URI « %s »"
+msgstr "Cap de grop es pas definit dins lo signet per l'URI « %s »"
#: glib/gbookmarkfile.c:3503 glib/gbookmarkfile.c:3711
#, fuzzy, c-format
@@ -4742,10 +4925,11 @@ msgstr ""
"Cap d'aplicacion nomenada « %s » a pas enregistrat un signet per « %s »"
#: glib/gbookmarkfile.c:3734
-#, c-format
+#, fuzzy, c-format
+#| msgid "Failed to expand exec line '%s' with URI '%s'"
msgid "Failed to expand exec line “%s” with URI “%s”"
msgstr ""
-"Fracàs del desvolopament de la linha de comanda « %s » per l’URI « %s »"
+"Fracàs del desvolopament de la linha de comanda « %s » per l'URI « %s »"
#: glib/gconvert.c:467
#, fuzzy
@@ -4759,7 +4943,8 @@ msgid "Partial character sequence at end of input"
msgstr "Sequéncia de caractèrs incompleta en fin d'entrada"
#: glib/gconvert.c:763
-#, c-format
+#, fuzzy, c-format
+#| msgid "Cannot convert fallback '%s' to codeset '%s'"
msgid "Cannot convert fallback “%s” to codeset “%s”"
msgstr ""
"Impossible de convertir lo caractèr de replec « %s » dins lo jòc de còdis « "
@@ -4790,10 +4975,9 @@ msgid "The local file URI “%s” may not include a “#”"
msgstr "L'URI de fichièr local « %s » pòt pas inclure un caractèr « # »"
#: glib/gconvert.c:1668
-#, fuzzy, c-format
-#| msgid "The URI '%s' is invalid"
+#, c-format
msgid "The URI “%s” is invalid"
-msgstr "L'URI « %s » es pas valid"
+msgstr "L’URI « %s » es pas valida"
#: glib/gconvert.c:1680
#, fuzzy, c-format
@@ -5028,37 +5212,37 @@ msgstr "dimenge"
#: glib/gdatetime.c:392
msgctxt "abbreviated weekday name"
msgid "Mon"
-msgstr "lun."
+msgstr "Dl"
#: glib/gdatetime.c:394
msgctxt "abbreviated weekday name"
msgid "Tue"
-msgstr "mar."
+msgstr "Dm"
#: glib/gdatetime.c:396
msgctxt "abbreviated weekday name"
msgid "Wed"
-msgstr "mèr."
+msgstr "Dc"
#: glib/gdatetime.c:398
msgctxt "abbreviated weekday name"
msgid "Thu"
-msgstr "jòu."
+msgstr "Dj"
#: glib/gdatetime.c:400
msgctxt "abbreviated weekday name"
msgid "Fri"
-msgstr "ven."
+msgstr "Dv"
#: glib/gdatetime.c:402
msgctxt "abbreviated weekday name"
msgid "Sat"
-msgstr "sab."
+msgstr "Ds"
#: glib/gdatetime.c:404
msgctxt "abbreviated weekday name"
msgid "Sun"
-msgstr "dim."
+msgstr "Dg"
#. Translators: Some languages need different grammatical forms of
#. * month names depending on whether they are standalone or in a full
@@ -5227,15 +5411,18 @@ msgid "PM"
msgstr "PM"
#: glib/gdir.c:154
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error opening directory '%s': %s"
msgid "Error opening directory “%s”: %s"
msgstr "Error a la dobertura del repertòri « %s » : %s"
#: glib/gfileutils.c:737 glib/gfileutils.c:829
-#, c-format
+#, fuzzy, c-format
+#| msgid "Could not allocate %lu byte to read file \"%s\""
+#| msgid_plural "Could not allocate %lu bytes to read file \"%s\""
msgid "Could not allocate %lu byte to read file “%s”"
msgid_plural "Could not allocate %lu bytes to read file “%s”"
-msgstr[0] "Impossible d'atribuir %lu octet per legir lo fichièr « %s »"
+msgstr[0] "Impossible d'alogar %lu octet per legir lo fichièr « %s »"
msgstr[1] "Impossible d'alogar %lu octets per legir lo fichièr « %s »"
#: glib/gfileutils.c:754
@@ -5244,8 +5431,7 @@ msgid "Error reading file “%s”: %s"
msgstr "Error de lectura del fichièr « %s » : %s"
#: glib/gfileutils.c:790
-#, fuzzy, c-format
-#| msgid "File \"%s\" is too large"
+#, c-format
msgid "File “%s” is too large"
msgstr "Lo fichièr « %s » es tròp grand"
@@ -5255,9 +5441,8 @@ msgstr "Lo fichièr « %s » es tròp grand"
msgid "Failed to read from file “%s”: %s"
msgstr "La lectura dempuèi lo fichièr « %s » a fracassat : %s"
-#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1476
-#, fuzzy, c-format
-#| msgid "Failed to open file '%s': %s"
+#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468
+#, c-format
msgid "Failed to open file “%s”: %s"
msgstr "La dobertura del fichièr « %s » a fracassat : %s"
@@ -5297,37 +5482,39 @@ msgid "Failed to write file “%s”: fsync() failed: %s"
msgstr ""
"L'escritura dins lo fichièr « %s » a fracassat : fracàs de fsync() : %s"
-#: glib/gfileutils.c:1365 glib/gfileutils.c:1780
-#, fuzzy, c-format
-#| msgid "Failed to create file '%s': %s"
+#: glib/gfileutils.c:1357 glib/gfileutils.c:1772
+#, c-format
msgid "Failed to create file “%s”: %s"
msgstr "La creacion del fichièr « %s » a fracassat : %s"
-#: glib/gfileutils.c:1410
+#: glib/gfileutils.c:1402
#, fuzzy, c-format
#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s"
msgid "Existing file “%s” could not be removed: g_unlink() failed: %s"
msgstr ""
"Lo fichièr existent « %s » pòt pas èsser suprimit : fracàs de g_unlink() : %s"
-#: glib/gfileutils.c:1745
-#, c-format
+#: glib/gfileutils.c:1737
+#, fuzzy, c-format
+#| msgid "Template '%s' invalid, should not contain a '%s'"
msgid "Template “%s” invalid, should not contain a “%s”"
msgstr "Lo modèl « %s » es pas valid, deuriá pas conténer un « %s »"
-#: glib/gfileutils.c:1758
-#, c-format
+#: glib/gfileutils.c:1750
+#, fuzzy, c-format
+#| msgid "Template '%s' doesn't contain XXXXXX"
msgid "Template “%s” doesn’t contain XXXXXX"
msgstr "Lo modèl « %s » conten pas XXXXXX"
-#: glib/gfileutils.c:2318 glib/gfileutils.c:2347
+#: glib/gfileutils.c:2310 glib/gfileutils.c:2339
#, fuzzy, c-format
#| msgid "Failed to read the symbolic link '%s': %s"
msgid "Failed to read the symbolic link “%s”: %s"
msgstr "La lectura del ligam simbolic « %s » a fracassat : %s"
#: glib/giochannel.c:1405
-#, c-format
+#, fuzzy, c-format
+#| msgid "Could not open converter from '%s' to '%s': %s"
msgid "Could not open converter from “%s” to “%s”: %s"
msgstr "Impossible de dobrir lo convertidor de « %s » cap a « %s » : %s"
@@ -5352,16 +5539,16 @@ msgstr "La canal s'acaba amb un caractèr parcial"
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "Lectura de donadas brutas impossibla dins g_io_channel_read_to_end"
-#: glib/gkeyfile.c:790
+#: glib/gkeyfile.c:789
msgid "Valid key file could not be found in search dirs"
msgstr ""
"Impossible de trobar un fichièr de claus valid dins los repertòris de recèrca"
-#: glib/gkeyfile.c:827
+#: glib/gkeyfile.c:826
msgid "Not a regular file"
msgstr "Es pas un fichièr estandard"
-#: glib/gkeyfile.c:1282
+#: glib/gkeyfile.c:1281
#, fuzzy, c-format
#| msgid ""
#| "Key file contains line '%s' which is not a key-value pair, group, or "
@@ -5372,21 +5559,21 @@ msgstr ""
"Lo fichièr de claus conten la linha « %s » qu'es pas ni una para de valors "
"de clau, ni un grop, ni un comentari"
-#: glib/gkeyfile.c:1339
+#: glib/gkeyfile.c:1338
#, c-format
msgid "Invalid group name: %s"
msgstr "Nom de grop invalid : %s"
-#: glib/gkeyfile.c:1361
+#: glib/gkeyfile.c:1360
msgid "Key file does not start with a group"
msgstr "Lo fichièr de claus comença pas per un grop"
-#: glib/gkeyfile.c:1387
+#: glib/gkeyfile.c:1386
#, c-format
msgid "Invalid key name: %s"
msgstr "Nom de clau invalid : %s"
-#: glib/gkeyfile.c:1414
+#: glib/gkeyfile.c:1413
#, fuzzy, c-format
#| msgid "Key file contains unsupported encoding '%s'"
msgid "Key file contains unsupported encoding “%s”"
@@ -5394,21 +5581,21 @@ msgstr ""
"Lo fichièr de claus conten un encodatge de caractèrs pas preses en carga « "
"%s »"
-#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289
-#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615
-#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063
+#: glib/gkeyfile.c:1662 glib/gkeyfile.c:1835 glib/gkeyfile.c:3288
+#: glib/gkeyfile.c:3352 glib/gkeyfile.c:3482 glib/gkeyfile.c:3614
+#: glib/gkeyfile.c:3760 glib/gkeyfile.c:3995 glib/gkeyfile.c:4062
#, fuzzy, c-format
#| msgid "Key file does not have group '%s'"
msgid "Key file does not have group “%s”"
msgstr "Lo fichièr de claus a pas de grop « %s »"
-#: glib/gkeyfile.c:1791
+#: glib/gkeyfile.c:1790
#, fuzzy, c-format
#| msgid "Key file does not have key '%s' in group '%s'"
msgid "Key file does not have key “%s” in group “%s”"
msgstr "Lo fichièr de claus conten pas de clau « %s » dins lo grop « %s »"
-#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069
+#: glib/gkeyfile.c:1952 glib/gkeyfile.c:2068
#, fuzzy, c-format
#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8"
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
@@ -5416,7 +5603,7 @@ msgstr ""
"Lo fichièr de claus conten la clau « %s » amb la valor « %s » qu'es pas "
"encodat en UTF-8"
-#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531
+#: glib/gkeyfile.c:1972 glib/gkeyfile.c:2088 glib/gkeyfile.c:2530
#, fuzzy, c-format
#| msgid ""
#| "Key file contains key '%s' which has a value that cannot be interpreted."
@@ -5426,7 +5613,7 @@ msgstr ""
"Lo fichièr de claus conten la clau « %s » qu'una valor n'es impossibla a "
"interpretar."
-#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118
+#: glib/gkeyfile.c:2748 glib/gkeyfile.c:3117
#, fuzzy, c-format
#| msgid ""
#| "Key file contains key '%s' in group '%s' which has a value that cannot be "
@@ -5438,7 +5625,7 @@ msgstr ""
"Lo fichièr de claus conten la clau « %s » dins lo grop « %s » qu'a una valor "
"impossibla a interpretar."
-#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904
+#: glib/gkeyfile.c:2826 glib/gkeyfile.c:2903
#, fuzzy, c-format
#| msgid "Key '%s' in group '%s' has value '%s' where %s was expected"
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
@@ -5446,36 +5633,36 @@ msgstr ""
"La clau « %s » dins lo grop « %s » a una valor « %s » mentre que %s èra "
"esperat"
-#: glib/gkeyfile.c:4306
+#: glib/gkeyfile.c:4305
msgid "Key file contains escape character at end of line"
msgstr "Lo fichièr de claus conten un caractèr d'escapament en fin de linha"
-#: glib/gkeyfile.c:4328
+#: glib/gkeyfile.c:4327
#, fuzzy, c-format
#| msgid "Key file contains invalid escape sequence '%s'"
msgid "Key file contains invalid escape sequence “%s”"
msgstr "Lo fichièr de claus conten una sequéncia d'escapament invalida « %s »"
-#: glib/gkeyfile.c:4472
+#: glib/gkeyfile.c:4471
#, fuzzy, c-format
#| msgid "Value '%s' cannot be interpreted as a number."
msgid "Value “%s” cannot be interpreted as a number."
msgstr "La valor « %s » pòt pas èsser interpretada coma un nombre."
-#: glib/gkeyfile.c:4486
+#: glib/gkeyfile.c:4485
#, fuzzy, c-format
#| msgid "Integer value '%s' out of range"
msgid "Integer value “%s” out of range"
msgstr "La valor entièra « %s » es fòra plaja"
-#: glib/gkeyfile.c:4519
+#: glib/gkeyfile.c:4518
#, fuzzy, c-format
#| msgid "Value '%s' cannot be interpreted as a float number."
msgid "Value “%s” cannot be interpreted as a float number."
msgstr ""
"La valor « %s » pòt pas èsser interpretada coma un nombre a virgula flotanta."
-#: glib/gkeyfile.c:4558
+#: glib/gkeyfile.c:4557
#, fuzzy, c-format
#| msgid "Value '%s' cannot be interpreted as a boolean."
msgid "Value “%s” cannot be interpreted as a boolean."
@@ -5517,7 +5704,8 @@ msgid "“%s” is not a valid name"
msgstr "« %s » es pas un nom valid"
#: glib/gmarkup.c:489
-#, c-format
+#, fuzzy, c-format
+#| msgid "'%s' is not a valid name: '%c'"
msgid "“%s” is not a valid name: “%c”"
msgstr "« %s » es pas un nom valid : « %c »"
@@ -5809,9 +5997,10 @@ msgid "Options:"
msgstr "Opcions :"
#: glib/goption.c:1125 glib/goption.c:1195
-#, c-format
+#, fuzzy, c-format
+#| msgid "Cannot parse integer value '%s' for %s"
msgid "Cannot parse integer value “%s” for %s"
-msgstr "Impossible d’analisar la valor entièra « %s » per %s"
+msgstr "Impossible d'analisar la valor entièra « %s » per %s"
#: glib/goption.c:1135 glib/goption.c:1203
#, fuzzy, c-format
@@ -5820,9 +6009,10 @@ msgid "Integer value “%s” for %s out of range"
msgstr "La valor entièra « %s » per %s es fòra plaja"
#: glib/goption.c:1160
-#, c-format
+#, fuzzy, c-format
+#| msgid "Cannot parse double value '%s' for %s"
msgid "Cannot parse double value “%s” for %s"
-msgstr "Impossible d’analisar la valor dobla « %s » per %s"
+msgstr "Impossible d'analisar la valor dobla « %s » per %s"
#: glib/goption.c:1168
#, fuzzy, c-format
@@ -5835,12 +6025,12 @@ msgstr "La valor dobla « %s » per %s es fòra plaja"
msgid "Error parsing option %s"
msgstr "Error al moment de l'analisi de l'opcion %s"
-#: glib/goption.c:1570 glib/goption.c:1683
+#: glib/goption.c:1561 glib/goption.c:1674
#, c-format
msgid "Missing argument for %s"
msgstr "Argument mancant per %s"
-#: glib/goption.c:2194
+#: glib/goption.c:2185
#, c-format
msgid "Unknown option %s"
msgstr "Opcion desconeguda %s"
@@ -6183,14 +6373,18 @@ msgid "Error while compiling regular expression %s at char %d: %s"
msgstr "Error a la compilation de l'expression regulara %s al caractèr %d : %s"
#: glib/gregex.c:2419
+#, fuzzy
+#| msgid "hexadecimal digit or '}' expected"
msgid "hexadecimal digit or “}” expected"
-msgstr "chifra exadecimala o « } » esperada"
+msgstr "chifra exadecimala o « } » esperat"
#: glib/gregex.c:2435
msgid "hexadecimal digit expected"
msgstr "chifra exadecimala esperat"
#: glib/gregex.c:2475
+#, fuzzy
+#| msgid "missing '<' in symbolic reference"
msgid "missing “<” in symbolic reference"
msgstr "« < » mancant dins la referéncia simbolica"
@@ -6221,10 +6415,11 @@ msgid "unknown escape sequence"
msgstr "sequéncia d'escapament desconeguda"
#: glib/gregex.c:2597
-#, c-format
+#, fuzzy, c-format
+#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s"
msgid "Error while parsing replacement text “%s” at char %lu: %s"
msgstr ""
-"Error al moment de l’analisi del tèxte de substitucion « %s » al caractèr "
+"Error al moment de l'analisi del tèxte de substitucion « %s » al caractèr "
"%lu : %s"
#: glib/gshell.c:94
@@ -6259,89 +6454,91 @@ msgstr ""
msgid "Text was empty (or contained only whitespace)"
msgstr "Lo tèxte èra void (o conteniá pas que d'espacis)"
-#: glib/gspawn.c:318
+#: glib/gspawn.c:308
#, c-format
msgid "Failed to read data from child process (%s)"
msgstr "La lectura de las donadas dempuèi lo processus filh a fracassat (%s)"
-#: glib/gspawn.c:465
-#, c-format
+#: glib/gspawn.c:455
+#, fuzzy, c-format
+#| msgid "Unexpected error in select() reading data from a child process (%s)"
msgid "Unexpected error in reading data from a child process (%s)"
msgstr ""
"Error inesperada dins select() a la lectura de las donadas dempuèi un "
"processus filh (%s)"
-#: glib/gspawn.c:550
+#: glib/gspawn.c:540
#, c-format
msgid "Unexpected error in waitpid() (%s)"
msgstr "Error inesperada dins waitpid() (%s)"
-#: glib/gspawn.c:1154 glib/gspawn-win32.c:1383
+#: glib/gspawn.c:1144 glib/gspawn-win32.c:1383
#, c-format
msgid "Child process exited with code %ld"
msgstr "Lo processus filh s'es acabat amb lo còdi %ld"
-#: glib/gspawn.c:1162
+#: glib/gspawn.c:1152
#, c-format
msgid "Child process killed by signal %ld"
msgstr "Lo processus filh es estat tuat pel senhal %ld"
-#: glib/gspawn.c:1169
+#: glib/gspawn.c:1159
#, c-format
msgid "Child process stopped by signal %ld"
msgstr "Lo processus filh es estat arrestat pel senhal %ld"
-#: glib/gspawn.c:1176
+#: glib/gspawn.c:1166
#, c-format
msgid "Child process exited abnormally"
msgstr "Lo processus filh s'es acabat anormalement"
-#: glib/gspawn.c:1767 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1757 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
#, c-format
msgid "Failed to read from child pipe (%s)"
msgstr "La lectura dempuèi un tub filh a fracassat (%s)"
-#: glib/gspawn.c:2069
+#: glib/gspawn.c:2059
#, fuzzy, c-format
#| msgid "Failed to fork child process (%s)"
msgid "Failed to spawn child process “%s” (%s)"
msgstr "Lo clonatge del processus filh a fracassat (%s)"
-#: glib/gspawn.c:2186
+#: glib/gspawn.c:2176
#, c-format
msgid "Failed to fork (%s)"
msgstr "Lo clonatge a fracassat (%s)"
-#: glib/gspawn.c:2346 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2336 glib/gspawn-win32.c:381
#, fuzzy, c-format
#| msgid "Failed to change to directory '%s' (%s)"
msgid "Failed to change to directory “%s” (%s)"
msgstr "Lo cambiament de repertòri « %s » a fracassat (%s)"
-#: glib/gspawn.c:2356
+#: glib/gspawn.c:2346
#, fuzzy, c-format
#| msgid "Failed to execute child process \"%s\" (%s)"
msgid "Failed to execute child process “%s” (%s)"
msgstr "L'execucion del processus filh « %s » a fracassat (%s)"
-#: glib/gspawn.c:2366
+#: glib/gspawn.c:2356
#, c-format
msgid "Failed to redirect output or input of child process (%s)"
msgstr ""
"La redireccion de la sortida o de l'entrada del processus filh a fracassat "
"(%s)"
-#: glib/gspawn.c:2375
+#: glib/gspawn.c:2365
#, c-format
msgid "Failed to fork child process (%s)"
msgstr "Lo clonatge del processus filh a fracassat (%s)"
-#: glib/gspawn.c:2383
-#, c-format
+#: glib/gspawn.c:2373
+#, fuzzy, c-format
+#| msgid "Unknown error executing child process \"%s\""
msgid "Unknown error executing child process “%s”"
-msgstr "Error desconeguda a l’execucion del processus filh « %s »"
+msgstr "Error desconeguda a l'execucion del processus filh « %s »"
-#: glib/gspawn.c:2407
+#: glib/gspawn.c:2397
#, c-format
msgid "Failed to read enough data from child pid pipe (%s)"
msgstr ""
@@ -6398,12 +6595,12 @@ msgstr ""
#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440
msgid "Empty string is not a number"
-msgstr "Una cadena voida es pas un nombre"
+msgstr ""
#: glib/gstrfuncs.c:3362
#, c-format
msgid "“%s” is not a signed number"
-msgstr "« %s » es pas un nombre signat"
+msgstr "« %s » es pas un nombre valid"
#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476
#, c-format
@@ -6411,14 +6608,16 @@ msgid "Number “%s” is out of bounds [%s, %s]"
msgstr ""
#: glib/gstrfuncs.c:3466
-#, c-format
+#, fuzzy, c-format
+#| msgid "'%s' is not a valid name"
msgid "“%s” is not an unsigned number"
-msgstr "« %s » es pas un nombre pas signat"
+msgstr "« %s » es pas un nom valid"
#: glib/guri.c:315
-#, no-c-format
+#, fuzzy, no-c-format
+#| msgid " (invalid encoding)"
msgid "Invalid %-encoding in URI"
-msgstr "%-encoding invalid dins l'URI"
+msgstr " (encodatge invalid)"
#: glib/guri.c:332
msgid "Illegal character in URI"
@@ -6451,22 +6650,21 @@ msgstr "Impossible d’analisar lo pòrt « %.*s » dins l’URI"
#: glib/guri.c:664
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
-msgstr "Lo pòrt « %.*s » dins l’URI es fòra plaja"
+msgstr ""
#: glib/guri.c:1224 glib/guri.c:1288
-#, fuzzy, c-format
-#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme"
+#, c-format
msgid "URI ‘%s’ is not an absolute URI"
-msgstr "L'URI « %s » es pas una URI absoluda qu'utiliza lo protocòl « file »"
+msgstr "L’URI « %s » es pas una URI absoluta"
#: glib/guri.c:1230
#, c-format
msgid "URI ‘%s’ has no host component"
-msgstr "L’URI « %s » a pas de component òste"
+msgstr ""
#: glib/guri.c:1435
msgid "URI is not absolute, and no base URI was provided"
-msgstr "L'URI es pas absoluda, e cap d'URI de basa es pas estada provesida"
+msgstr ""
#: glib/guri.c:2209
msgid "Missing ‘=’ and parameter value"
@@ -6499,79 +6697,79 @@ msgstr "%.1f ko"
#: glib/gutils.c:2769
#, c-format
msgid "%.1f MB"
-msgstr "%.1f Mo"
+msgstr "%.1f Mo"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2771
#, c-format
msgid "%.1f GB"
-msgstr "%.1f Go"
+msgstr "%.1f Go"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2773
#, c-format
msgid "%.1f TB"
-msgstr "%.1f To"
+msgstr "%.1f To"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2775
#, c-format
msgid "%.1f PB"
-msgstr "%.1f Po"
+msgstr "%.1f Po"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2777
#, c-format
msgid "%.1f EB"
-msgstr "%.1f Eo"
+msgstr "%.1f Eo"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2781
#, c-format
msgid "%.1f KiB"
-msgstr "%.1f Kio"
+msgstr "%.1f Kio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2783
#, c-format
msgid "%.1f MiB"
-msgstr "%.1f Mio"
+msgstr "%.1f Mio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2785
#, c-format
msgid "%.1f GiB"
-msgstr "%.1f Gio"
+msgstr "%.1f Gio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2787
#, c-format
msgid "%.1f TiB"
-msgstr "%.1f Tio"
+msgstr "%.1f Tio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2789
#, c-format
msgid "%.1f PiB"
-msgstr "%.1f Pio"
+msgstr "%.1f Pio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2791
#, c-format
msgid "%.1f EiB"
-msgstr "%.1f Eio"
+msgstr "%.1f Eio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2795
#, c-format
msgid "%.1f kb"
-msgstr "%.1f kb"
+msgstr "%.1f kb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2797
#, c-format
msgid "%.1f Mb"
-msgstr "%.1f Mb"
+msgstr "%.1f Mb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2799
@@ -6583,13 +6781,13 @@ msgstr "%.1f Gb"
#: glib/gutils.c:2801
#, c-format
msgid "%.1f Tb"
-msgstr "%.1f Tb"
+msgstr "%.1f Tb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2803
#, c-format
msgid "%.1f Pb"
-msgstr "%.1f Pb"
+msgstr "%.1f Pb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2805
@@ -6601,37 +6799,37 @@ msgstr "%.1f Eb"
#: glib/gutils.c:2809
#, c-format
msgid "%.1f Kib"
-msgstr "%.1f Kib"
+msgstr "%.1f Kio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2811
#, c-format
msgid "%.1f Mib"
-msgstr "%.1f Mib"
+msgstr "%.1f Mio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2813
#, c-format
msgid "%.1f Gib"
-msgstr "%.1f Gib"
+msgstr "%.1f Gio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2815
#, c-format
msgid "%.1f Tib"
-msgstr "%.1f Tib"
+msgstr "%.1f Tio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2817
#, c-format
msgid "%.1f Pib"
-msgstr "%.1f Pib"
+msgstr "%.1f Pio"
#. Translators: Keep the no-break space between %.1f and the unit symbol
#: glib/gutils.c:2819
#, c-format
msgid "%.1f Eib"
-msgstr "%.1f Eib"
+msgstr "%.1f Eio"
#: glib/gutils.c:2853 glib/gutils.c:2970
#, c-format
diff --git a/po/sr.po b/po/sr.po
index 337f86f06..957e86ea1 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -12,9 +12,9 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.8\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2021-04-08 13:42+0000\n"
-"PO-Revision-Date: 2021-04-11 20:17+0200\n"
-"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
+"POT-Creation-Date: 2021-03-18 14:00+0000\n"
+"PO-Revision-Date: 2021-03-19 08:29+0100\n"
+"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n"
"Language-Team: српски <gnome-sr@googlegroups.org>\n"
"Language: sr\n"
"MIME-Version: 1.0\n"
@@ -23,6 +23,7 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n"
+"X-Generator: Poedit 2.4.2\n"
#: gio/gapplication.c:500
msgid "GApplication options"
@@ -966,7 +967,6 @@ msgstr "Не могу да добавим профил физичких дело
#. Translators: Both placeholders are file paths
#: gio/gdbusprivate.c:2494
#, c-format
-#| msgid "Unable to load ‘%s‘: %s"
msgid "Unable to load %s or %s: "
msgstr "Не могу да учитам „%s“ или „%s“: "
@@ -3983,36 +3983,36 @@ msgstr "Грешка у затварању утичнице: %s"
msgid "Waiting for socket condition: %s"
msgstr "Чекам услов утичнице: %s"
-#: gio/gsocket.c:4806 gio/gsocket.c:4824 gio/gsocket.c:4837
+#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833
#, c-format
msgid "Unable to send message: %s"
msgstr "Не могу да пошаљем поруку: %s"
-#: gio/gsocket.c:4807 gio/gsocket.c:4825 gio/gsocket.c:4838
+#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834
msgid "Message vectors too large"
msgstr "Вектори поруке су превелики"
-#: gio/gsocket.c:4854 gio/gsocket.c:4856 gio/gsocket.c:5003 gio/gsocket.c:5088
-#: gio/gsocket.c:5266 gio/gsocket.c:5306 gio/gsocket.c:5308
+#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084
+#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304
#, c-format
msgid "Error sending message: %s"
msgstr "Грешка при слању поруке: %s"
-#: gio/gsocket.c:5030
+#: gio/gsocket.c:5026
msgid "GSocketControlMessage not supported on Windows"
msgstr "Порука управљања Гутичницом није подржана на Виндоузу"
-#: gio/gsocket.c:5499 gio/gsocket.c:5575 gio/gsocket.c:5801
+#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797
#, c-format
msgid "Error receiving message: %s"
msgstr "Грешка при примању поруке: %s"
-#: gio/gsocket.c:6074 gio/gsocket.c:6085 gio/gsocket.c:6131
+#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "Не могу да прочитам уверења утичнице: %s"
-#: gio/gsocket.c:6140
+#: gio/gsocket.c:6136
msgid "g_socket_get_credentials not implemented for this OS"
msgstr "г_утичница_добавља_уверења није примењена за овај оперативни систем"
@@ -5019,16 +5019,16 @@ msgstr "Канал се завршава делимичним знаком"
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "Не могу да читам без обраде у г_уи_каналу_читај_до_краја"
-#: glib/gkeyfile.c:790
+#: glib/gkeyfile.c:789
msgid "Valid key file could not be found in search dirs"
msgstr ""
"Не могу да нађем исправну датотеку са кључевима међу директоријумима претраге"
-#: glib/gkeyfile.c:827
+#: glib/gkeyfile.c:826
msgid "Not a regular file"
msgstr "Није обична датотека"
-#: glib/gkeyfile.c:1282
+#: glib/gkeyfile.c:1281
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
@@ -5036,49 +5036,49 @@ msgstr ""
"Датотека са кључевима садржи ред „%s“ што не чини пар кључ-вредност, групу "
"или примедбу"
-#: glib/gkeyfile.c:1339
+#: glib/gkeyfile.c:1338
#, c-format
msgid "Invalid group name: %s"
msgstr "Неисправан назив групе: %s"
-#: glib/gkeyfile.c:1361
+#: glib/gkeyfile.c:1360
msgid "Key file does not start with a group"
msgstr "Датотека са кључевима не почиње групом"
-#: glib/gkeyfile.c:1387
+#: glib/gkeyfile.c:1386
#, c-format
msgid "Invalid key name: %s"
msgstr "Неисправан назив кључа: %s"
-#: glib/gkeyfile.c:1414
+#: glib/gkeyfile.c:1413
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "Датотека са кључевима садржи неподржано кодирање „%s“"
-#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289
-#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615
-#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063
+#: glib/gkeyfile.c:1662 glib/gkeyfile.c:1835 glib/gkeyfile.c:3288
+#: glib/gkeyfile.c:3352 glib/gkeyfile.c:3482 glib/gkeyfile.c:3614
+#: glib/gkeyfile.c:3760 glib/gkeyfile.c:3995 glib/gkeyfile.c:4062
#, c-format
msgid "Key file does not have group “%s”"
msgstr "Датотека са кључевима нема групу „%s“"
-#: glib/gkeyfile.c:1791
+#: glib/gkeyfile.c:1790
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "Датотека са кључевима не садржи кључ „%s“ у групи „%s“"
-#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069
+#: glib/gkeyfile.c:1952 glib/gkeyfile.c:2068
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "Датотека са кључевима садржи кључ „%s“ вредности „%s“ што није УТФ-8"
-#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531
+#: glib/gkeyfile.c:1972 glib/gkeyfile.c:2088 glib/gkeyfile.c:2530
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
msgstr "Датотека са кључевима садржи кључ „%s“ неразумљиве вредности."
-#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118
+#: glib/gkeyfile.c:2748 glib/gkeyfile.c:3117
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
@@ -5086,36 +5086,36 @@ msgid ""
msgstr ""
"Датотека са кључевима садржи кључ „%s“ у групи „%s“ неразумљиве вредности."
-#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904
+#: glib/gkeyfile.c:2826 glib/gkeyfile.c:2903
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "Кључ „%s“ у групи „%s“ има вредност „%s“ где је очекивано %s"
-#: glib/gkeyfile.c:4306
+#: glib/gkeyfile.c:4305
msgid "Key file contains escape character at end of line"
msgstr "Датотека са кључевима садржи знак истицања на крају реда"
-#: glib/gkeyfile.c:4328
+#: glib/gkeyfile.c:4327
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "Датотека са кључевима садржи недозвољен низ истицања „%s“"
-#: glib/gkeyfile.c:4472
+#: glib/gkeyfile.c:4471
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "Вредност „%s“ се не може сматрати бројем."
-#: glib/gkeyfile.c:4486
+#: glib/gkeyfile.c:4485
#, c-format
msgid "Integer value “%s” out of range"
msgstr "Целобројна вредност „%s“ је изван опсега"
-#: glib/gkeyfile.c:4519
+#: glib/gkeyfile.c:4518
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "Вредност „%s“ се не може сматрати реалним бројем једноструке тачности."
-#: glib/gkeyfile.c:4558
+#: glib/gkeyfile.c:4557
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "Вредност „%s“ се не може сматрати истинитосном."
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 547b5e7b9..776d6c446 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -20,9 +20,9 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: glib 2.68\n"
+"Project-Id-Version: glib master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2021-06-15 18:41+0000\n"
+"POT-Creation-Date: 2021-03-22 11:48+0000\n"
"PO-Revision-Date: 2021-03-28 01:17+0800\n"
"Last-Translator: Dingzhong Chen <wsxy162@gmail.com>\n"
"Language-Team: Chinese - China <i18n-zh@googlegroups.com>\n"
@@ -627,7 +627,7 @@ msgstr "打开钥匙环“%s”以写入时出错:"
#: gio/gdbusauthmechanismsha1.c:908
#, c-format
msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
-msgstr "(此外,解除“%s”的锁定也失败了:%s)"
+msgstr "(此外,解除“%s”的锁定也失败了:%s) "
#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2405
msgid "The connection is closed"
@@ -1378,7 +1378,7 @@ msgstr "无法复制特殊文件"
msgid "Invalid symlink value given"
msgstr "给定的符号链接值无效"
-#: gio/gfile.c:4045 glib/gfileutils.c:2362
+#: gio/gfile.c:4045 glib/gfileutils.c:2354
msgid "Symbolic links not supported"
msgstr "不支持符号链接"
@@ -1871,7 +1871,7 @@ msgstr "无法加载“%s”的应用程序信息"
#: gio/gio-tool-launch.c:119
#, c-format
msgid "Unable to launch application ‘%s’: %s"
-msgstr "无法启动应用程序“%s”:%s"
+msgstr "无法启动应用程序“%s”: %s"
#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32
msgid "Show hidden files"
@@ -2264,7 +2264,7 @@ msgstr "无法找到原始路径"
#: gio/gio-tool-trash.c:123
msgid "Unable to recreate original location: "
-msgstr "无法重新创建原始位置:"
+msgstr "无法创建原始位置:"
#: gio/gio-tool-trash.c:136
msgid "Unable to move file to its original location: "
@@ -2272,7 +2272,7 @@ msgstr "无法移动文件回它的原始位置:"
#: gio/gio-tool-trash.c:225
msgid "Move/Restore files or directories to the trash."
-msgstr "移动/恢复文件或目录到回收站。"
+msgstr "移动/还原文件或目录到回收站。"
#: gio/gio-tool-trash.c:227
msgid ""
@@ -3000,9 +3000,9 @@ msgstr "移动文件 %s 时出错:%s"
msgid "Can’t move directory over directory"
msgstr "无法将目录移动到目录"
-#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1108
-#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137
-#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168
+#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1079
+#: gio/glocalfileoutputstream.c:1093 gio/glocalfileoutputstream.c:1108
+#: gio/glocalfileoutputstream.c:1125 gio/glocalfileoutputstream.c:1139
msgid "Backup file creation failed"
msgstr "备份文件创建失败"
@@ -3039,10 +3039,9 @@ msgstr "设置扩展属性“%s”时出错:%s"
#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
-msgstr "(无效的编码)"
+msgstr " (无效的编码)"
#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943
-#: gio/glocalfileoutputstream.c:995
#, c-format
msgid "Error when getting information for file “%s”: %s"
msgstr "获取文件“%s”的信息时出错:%s"
@@ -3162,7 +3161,7 @@ msgid "Error closing file: %s"
msgstr "关闭文件出错:%s"
#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563
-#: gio/glocalfileoutputstream.c:1186
+#: gio/glocalfileoutputstream.c:1157
#, c-format
msgid "Error seeking in file: %s"
msgstr "在文件中定位时出错:%s"
@@ -3192,13 +3191,13 @@ msgstr "创建备份拷贝:%s"
msgid "Error renaming temporary file: %s"
msgstr "重命名临时文件出错:%s"
-#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237
+#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1208
#, c-format
msgid "Error truncating file: %s"
msgstr "截断文件出错:%s"
#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907
-#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226
+#: gio/glocalfileoutputstream.c:1189 gio/gsubprocess.c:226
#, c-format
msgid "Error opening file “%s”: %s"
msgstr "打开文件“%s”出错:%s"
@@ -3211,11 +3210,11 @@ msgstr "目标文件是目录"
msgid "Target file is not a regular file"
msgstr "目标文件不是普通文件"
-#: gio/glocalfileoutputstream.c:1013
+#: gio/glocalfileoutputstream.c:984
msgid "The file was externally modified"
msgstr "文件已经被其他程序修改"
-#: gio/glocalfileoutputstream.c:1202
+#: gio/glocalfileoutputstream.c:1173
#, c-format
msgid "Error removing old file: %s"
msgstr "移除旧文件出错:%s"
@@ -3884,36 +3883,36 @@ msgstr "关闭套接字时出错:%s"
msgid "Waiting for socket condition: %s"
msgstr "等待套接字状态:%s"
-#: gio/gsocket.c:4806 gio/gsocket.c:4824 gio/gsocket.c:4837
+#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833
#, c-format
msgid "Unable to send message: %s"
-msgstr "无法发送消息:%s"
+msgstr "无法发送信息:%s"
-#: gio/gsocket.c:4807 gio/gsocket.c:4825 gio/gsocket.c:4838
+#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834
msgid "Message vectors too large"
msgstr "信息向量过大"
-#: gio/gsocket.c:4854 gio/gsocket.c:4856 gio/gsocket.c:5003 gio/gsocket.c:5088
-#: gio/gsocket.c:5266 gio/gsocket.c:5306 gio/gsocket.c:5308
+#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084
+#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304
#, c-format
msgid "Error sending message: %s"
msgstr "发送信息时出错:%s"
-#: gio/gsocket.c:5030
+#: gio/gsocket.c:5026
msgid "GSocketControlMessage not supported on Windows"
msgstr "Windows 不支持 GSocketControlMessage"
-#: gio/gsocket.c:5499 gio/gsocket.c:5575 gio/gsocket.c:5801
+#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797
#, c-format
msgid "Error receiving message: %s"
msgstr "接受信息时出错:%s"
-#: gio/gsocket.c:6074 gio/gsocket.c:6085 gio/gsocket.c:6131
+#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "无法读取套接字认证信息:%s"
-#: gio/gsocket.c:6140
+#: gio/gsocket.c:6136
msgid "g_socket_get_credentials not implemented for this OS"
msgstr "此操作系统上没有实现 g_socket_get_credentials"
@@ -4064,29 +4063,29 @@ msgstr "暂时无法解析“%s”"
msgid "Error resolving “%s”"
msgstr "解析“%s”时出错"
-#: gio/gtlscertificate.c:299
+#: gio/gtlscertificate.c:298
msgid "No PEM-encoded private key found"
msgstr "未找到 PEM 加密的私钥"
-#: gio/gtlscertificate.c:309
+#: gio/gtlscertificate.c:308
msgid "Cannot decrypt PEM-encoded private key"
msgstr "无法解密 PEM 加密的私钥"
-#: gio/gtlscertificate.c:320
+#: gio/gtlscertificate.c:319
msgid "Could not parse PEM-encoded private key"
msgstr "无法解析 PEM 加密的私钥"
-#: gio/gtlscertificate.c:347
+#: gio/gtlscertificate.c:346
msgid "No PEM-encoded certificate found"
msgstr "未找到 PEM 加密的证书"
-#: gio/gtlscertificate.c:356
+#: gio/gtlscertificate.c:355
msgid "Could not parse PEM-encoded certificate"
msgstr "无法解析 PEM 加密的证书"
-#: gio/gtlscertificate.c:711
+#: gio/gtlscertificate.c:710
msgid "This GTlsBackend does not support creating PKCS #11 certificates"
-msgstr "此 GTlsBackend 不支持创建 PKCS #11 证书"
+msgstr "本 GTlsBackend 不支持创建 PKCS #11 证书"
#: gio/gtlspassword.c:111
msgid ""
@@ -4818,7 +4817,7 @@ msgstr "文件“%s”过大"
msgid "Failed to read from file “%s”: %s"
msgstr "读取文件“%s”失败:%s"
-#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1476
+#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468
#, c-format
msgid "Failed to open file “%s”: %s"
msgstr "打开文件“%s”失败:%s"
@@ -4848,27 +4847,27 @@ msgstr "写入文件“%s”失败:write() 失败:%s"
msgid "Failed to write file “%s”: fsync() failed: %s"
msgstr "写入文件“%s”失败:fsync() 失败:%s"
-#: glib/gfileutils.c:1365 glib/gfileutils.c:1780
+#: glib/gfileutils.c:1357 glib/gfileutils.c:1772
#, c-format
msgid "Failed to create file “%s”: %s"
msgstr "创建文件“%s”失败:%s"
-#: glib/gfileutils.c:1410
+#: glib/gfileutils.c:1402
#, c-format
msgid "Existing file “%s” could not be removed: g_unlink() failed: %s"
msgstr "无法删除已有文件“%s”:g_unlink() 失败:%s"
-#: glib/gfileutils.c:1745
+#: glib/gfileutils.c:1737
#, c-format
msgid "Template “%s” invalid, should not contain a “%s”"
msgstr "模板“%s”无效,不应该包含“%s”"
-#: glib/gfileutils.c:1758
+#: glib/gfileutils.c:1750
#, c-format
msgid "Template “%s” doesn’t contain XXXXXX"
msgstr "模板“%s”不包含 XXXXXX"
-#: glib/gfileutils.c:2318 glib/gfileutils.c:2347
+#: glib/gfileutils.c:2310 glib/gfileutils.c:2339
#, c-format
msgid "Failed to read the symbolic link “%s”: %s"
msgstr "读取符号链接“%s”失败:%s"
@@ -4894,99 +4893,99 @@ msgstr "通道终止于未尽字符"
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "g_io_channel_read_to_end 函数无法进行原始读取"
-#: glib/gkeyfile.c:790
+#: glib/gkeyfile.c:789
msgid "Valid key file could not be found in search dirs"
msgstr "在搜索目录中无法找到有效的键文件"
-#: glib/gkeyfile.c:827
+#: glib/gkeyfile.c:826
msgid "Not a regular file"
msgstr "不是普通文件"
-#: glib/gkeyfile.c:1282
+#: glib/gkeyfile.c:1281
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
msgstr "键文件包含不是键-值对、组或注释的行“%s”"
-#: glib/gkeyfile.c:1339
+#: glib/gkeyfile.c:1338
#, c-format
msgid "Invalid group name: %s"
msgstr "无效的组名:%s"
-#: glib/gkeyfile.c:1361
+#: glib/gkeyfile.c:1360
msgid "Key file does not start with a group"
msgstr "键文件不以组开始"
-#: glib/gkeyfile.c:1387
+#: glib/gkeyfile.c:1386
#, c-format
msgid "Invalid key name: %s"
msgstr "无效的键名:%s"
-#: glib/gkeyfile.c:1414
+#: glib/gkeyfile.c:1413
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "键文件包含不支持的编码“%s”"
-#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289
-#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615
-#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063
+#: glib/gkeyfile.c:1662 glib/gkeyfile.c:1835 glib/gkeyfile.c:3288
+#: glib/gkeyfile.c:3352 glib/gkeyfile.c:3482 glib/gkeyfile.c:3614
+#: glib/gkeyfile.c:3760 glib/gkeyfile.c:3995 glib/gkeyfile.c:4062
#, c-format
msgid "Key file does not have group “%s”"
msgstr "键文件没有组“%s”"
-#: glib/gkeyfile.c:1791
+#: glib/gkeyfile.c:1790
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "键文件在组“%2$s”中没有键“%1$s”"
-#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069
+#: glib/gkeyfile.c:1952 glib/gkeyfile.c:2068
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "键文件包含键“%s”,其值“%s”不是 UTF-8"
-#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531
+#: glib/gkeyfile.c:1972 glib/gkeyfile.c:2088 glib/gkeyfile.c:2530
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
msgstr "键文件包含键“%s”,其值无法解析。"
-#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118
+#: glib/gkeyfile.c:2748 glib/gkeyfile.c:3117
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
"interpreted."
msgstr "键文件包含组“%2$s”中的键“%1$s”,其值无法解释。"
-#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904
+#: glib/gkeyfile.c:2826 glib/gkeyfile.c:2903
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "组“%2$s”中的键“%1$s”的值为“%3$s”,应为 %4$s"
-#: glib/gkeyfile.c:4306
+#: glib/gkeyfile.c:4305
msgid "Key file contains escape character at end of line"
msgstr "键文件在行尾含有转义字符"
-#: glib/gkeyfile.c:4328
+#: glib/gkeyfile.c:4327
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "键文件中包含无效的转义序列“%s”"
-#: glib/gkeyfile.c:4472
+#: glib/gkeyfile.c:4471
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "无法将值“%s”解释为数值。"
-#: glib/gkeyfile.c:4486
+#: glib/gkeyfile.c:4485
#, c-format
msgid "Integer value “%s” out of range"
msgstr "整数值“%s”超出范围"
-#: glib/gkeyfile.c:4519
+#: glib/gkeyfile.c:4518
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "无法将值“%s”解释为浮点数。"
-#: glib/gkeyfile.c:4558
+#: glib/gkeyfile.c:4557
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "无法将值“%s”解释为布尔值。"
@@ -5009,7 +5008,7 @@ msgstr "打开文件“%s”失败:open() 失败:%s"
#: glib/gmarkup.c:398 glib/gmarkup.c:440
#, c-format
msgid "Error on line %d char %d: "
-msgstr "第 %d 行第 %d 个字符出错:"
+msgstr "第 %d 行第 %d 个字符出错: "
#: glib/gmarkup.c:462 glib/gmarkup.c:545
#, c-format
@@ -5248,12 +5247,12 @@ msgstr "%2$s 所用的双精度值“%1$s”超出范围"
msgid "Error parsing option %s"
msgstr "解析选项 %s 时出错"
-#: glib/goption.c:1570 glib/goption.c:1683
+#: glib/goption.c:1561 glib/goption.c:1674
#, c-format
msgid "Missing argument for %s"
msgstr "缺少 %s 的参数"
-#: glib/goption.c:2194
+#: glib/goption.c:2185
#, c-format
msgid "Unknown option %s"
msgstr "未知选项 %s"
@@ -5645,82 +5644,82 @@ msgstr "在找到为 %c 匹配的引用之前,文本已结束。(文本为
msgid "Text was empty (or contained only whitespace)"
msgstr "文本为空(或仅含空白字符)"
-#: glib/gspawn.c:318
+#: glib/gspawn.c:308
#, c-format
msgid "Failed to read data from child process (%s)"
msgstr "从子进程中读取数据失败(%s)"
-#: glib/gspawn.c:465
+#: glib/gspawn.c:455
#, c-format
msgid "Unexpected error in reading data from a child process (%s)"
msgstr "在从子进程中读取数据时出现异常错误(%s)"
-#: glib/gspawn.c:550
+#: glib/gspawn.c:540
#, c-format
msgid "Unexpected error in waitpid() (%s)"
msgstr "waitpid() 出现异常错误(%s)"
-#: glib/gspawn.c:1154 glib/gspawn-win32.c:1383
+#: glib/gspawn.c:1144 glib/gspawn-win32.c:1383
#, c-format
msgid "Child process exited with code %ld"
msgstr "子进程已退出,代码 %ld"
-#: glib/gspawn.c:1162
+#: glib/gspawn.c:1152
#, c-format
msgid "Child process killed by signal %ld"
msgstr "子进程已由信号 %ld 杀死"
-#: glib/gspawn.c:1169
+#: glib/gspawn.c:1159
#, c-format
msgid "Child process stopped by signal %ld"
msgstr "子进程已由信号 %ld 停止"
-#: glib/gspawn.c:1176
+#: glib/gspawn.c:1166
#, c-format
msgid "Child process exited abnormally"
msgstr "子进程异常中止"
-#: glib/gspawn.c:1767 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1757 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
#, c-format
msgid "Failed to read from child pipe (%s)"
msgstr "从子管道中读取失败(%s)"
-#: glib/gspawn.c:2069
+#: glib/gspawn.c:2059
#, c-format
msgid "Failed to spawn child process “%s” (%s)"
msgstr "生成子进程“%s”失败(%s)"
-#: glib/gspawn.c:2186
+#: glib/gspawn.c:2176
#, c-format
msgid "Failed to fork (%s)"
msgstr "fork 失败(%s)"
-#: glib/gspawn.c:2346 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2336 glib/gspawn-win32.c:381
#, c-format
msgid "Failed to change to directory “%s” (%s)"
msgstr "切换到目录“%s”失败(%s)"
-#: glib/gspawn.c:2356
+#: glib/gspawn.c:2346
#, c-format
msgid "Failed to execute child process “%s” (%s)"
msgstr "执行子进程“%s”失败(%s)"
-#: glib/gspawn.c:2366
+#: glib/gspawn.c:2356
#, c-format
msgid "Failed to redirect output or input of child process (%s)"
msgstr "重定位子进程(%s)的输入或输出失败"
-#: glib/gspawn.c:2375
+#: glib/gspawn.c:2365
#, c-format
msgid "Failed to fork child process (%s)"
msgstr "fork 子进程失败(%s)"
-#: glib/gspawn.c:2383
+#: glib/gspawn.c:2373
#, c-format
msgid "Unknown error executing child process “%s”"
msgstr "执行子进程“%s”时出现未知错误"
-#: glib/gspawn.c:2407
+#: glib/gspawn.c:2397
#, c-format
msgid "Failed to read enough data from child pid pipe (%s)"
msgstr "从子进程管道中读取足够的数据失败(%s)"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 11eb59c35..dd7951f8a 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -10,17 +10,16 @@ msgid ""
msgstr ""
"Project-Id-Version: glib 2.64\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2021-03-27 11:34+0000\n"
-"PO-Revision-Date: 2021-04-26 06:53+0000\n"
-"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
-"Language-Team: Chinese (Traditional) <http://darkbear.ddns.net/projects/"
-"gnome-40/glib-glib-2-68-zh_tw/zh_Hant/>\n"
+"POT-Creation-Date: 2020-10-01 16:40+0000\n"
+"PO-Revision-Date: 2020-10-12 22:54+0800\n"
+"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
+"Language-Team: Chinese (Traditional) <zh-l10n@lists.linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.6\n"
+"X-Generator: Poedit 2.4.1\n"
#: gio/gapplication.c:500
msgid "GApplication options"
@@ -59,90 +58,90 @@ msgstr "顯示版本"
msgid "Print version information and exit"
msgstr "輸出版本資訊並離開"
-#: gio/gapplication-tool.c:53
+#: gio/gapplication-tool.c:52
msgid "List applications"
msgstr "列出應用程式"
-#: gio/gapplication-tool.c:54
+#: gio/gapplication-tool.c:53
msgid "List the installed D-Bus activatable applications (by .desktop files)"
msgstr "列出已安裝可使用 D-Bus 的應用程式 (依 .desktop 檔案)"
-#: gio/gapplication-tool.c:57
+#: gio/gapplication-tool.c:55
msgid "Launch an application"
msgstr "執行應用程式"
-#: gio/gapplication-tool.c:58
+#: gio/gapplication-tool.c:56
msgid "Launch the application (with optional files to open)"
msgstr "執行應用程式 (選擇性加上要開啟的檔案)"
-#: gio/gapplication-tool.c:59
+#: gio/gapplication-tool.c:57
msgid "APPID [FILE…]"
msgstr "APPID [FILE...]"
-#: gio/gapplication-tool.c:61
+#: gio/gapplication-tool.c:59
msgid "Activate an action"
msgstr "讓動作生效"
-#: gio/gapplication-tool.c:62
+#: gio/gapplication-tool.c:60
msgid "Invoke an action on the application"
msgstr "呼叫應用程式的動作"
-#: gio/gapplication-tool.c:63
+#: gio/gapplication-tool.c:61
msgid "APPID ACTION [PARAMETER]"
msgstr "APPID ACTION [PARAMETER]"
-#: gio/gapplication-tool.c:65
+#: gio/gapplication-tool.c:63
msgid "List available actions"
msgstr "列出可用的動作"
-#: gio/gapplication-tool.c:66
+#: gio/gapplication-tool.c:64
msgid "List static actions for an application (from .desktop file)"
msgstr "列出應用程式的靜態動作 (從 .desktop 檔案)"
-#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73
+#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71
msgid "APPID"
msgstr "APPID"
-#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106
+#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102
#: gio/gio-tool.c:224
msgid "COMMAND"
msgstr "指令"
-#: gio/gapplication-tool.c:72
+#: gio/gapplication-tool.c:70
msgid "The command to print detailed help for"
msgstr "顯示詳細求助的指令"
-#: gio/gapplication-tool.c:73
+#: gio/gapplication-tool.c:71
msgid "Application identifier in D-Bus format (eg: org.example.viewer)"
msgstr "D-Bus 格式的應用程式識別碼(例如:org.example.viewer)"
-#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738
+#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738
#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772
#: gio/gresource-tool.c:500 gio/gresource-tool.c:566
msgid "FILE"
msgstr "FILE"
-#: gio/gapplication-tool.c:74
+#: gio/gapplication-tool.c:72
msgid "Optional relative or absolute filenames, or URIs to open"
msgstr "選擇性相對或絕對的檔案名稱,或要開啟的 URI"
-#: gio/gapplication-tool.c:75
+#: gio/gapplication-tool.c:73
msgid "ACTION"
msgstr "動作"
-#: gio/gapplication-tool.c:75
+#: gio/gapplication-tool.c:73
msgid "The action name to invoke"
msgstr "要呼叫的動作名稱"
-#: gio/gapplication-tool.c:76
+#: gio/gapplication-tool.c:74
msgid "PARAMETER"
msgstr "參數"
-#: gio/gapplication-tool.c:76
+#: gio/gapplication-tool.c:74
msgid "Optional parameter to the action invocation, in GVariant format"
msgstr "動作呼叫時選擇性的參數,以 GVariant 格式"
-#: gio/gapplication-tool.c:98 gio/gresource-tool.c:531 gio/gsettings-tool.c:659
+#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659
#, c-format
msgid ""
"Unknown command %s\n"
@@ -151,26 +150,26 @@ msgstr ""
"不明指令 %s\n"
"\n"
-#: gio/gapplication-tool.c:103
+#: gio/gapplication-tool.c:101
msgid "Usage:\n"
msgstr "用法:\n"
-#: gio/gapplication-tool.c:116 gio/gresource-tool.c:556
+#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556
#: gio/gsettings-tool.c:694
msgid "Arguments:\n"
msgstr "引數:\n"
-#: gio/gapplication-tool.c:135 gio/gio-tool.c:224
+#: gio/gapplication-tool.c:133 gio/gio-tool.c:224
msgid "[ARGS…]"
msgstr "[ARGS...]"
-#: gio/gapplication-tool.c:136
+#: gio/gapplication-tool.c:134
#, c-format
msgid "Commands:\n"
msgstr "指令:\n"
#. Translators: do not translate 'help', but please translate 'COMMAND'.
-#: gio/gapplication-tool.c:148
+#: gio/gapplication-tool.c:146
#, c-format
msgid ""
"Use “%s help COMMAND” to get detailed help.\n"
@@ -179,7 +178,7 @@ msgstr ""
"使用「'%s help COMMAND」以取得詳細的求助。\n"
"\n"
-#: gio/gapplication-tool.c:167
+#: gio/gapplication-tool.c:165
#, c-format
msgid ""
"%s command requires an application id to directly follow\n"
@@ -188,13 +187,13 @@ msgstr ""
"%s 指令需要應用程式 id 直接跟隨\n"
"\n"
-#: gio/gapplication-tool.c:173
+#: gio/gapplication-tool.c:171
#, c-format
msgid "invalid application id: “%s”\n"
msgstr "無效的應用程式 id:「%s」\n"
#. Translators: %s is replaced with a command name like 'list-actions'
-#: gio/gapplication-tool.c:184
+#: gio/gapplication-tool.c:182
#, c-format
msgid ""
"“%s” takes no arguments\n"
@@ -203,21 +202,21 @@ msgstr ""
"「%s」不需要引數\n"
"\n"
-#: gio/gapplication-tool.c:268
+#: gio/gapplication-tool.c:266
#, c-format
msgid "unable to connect to D-Bus: %s\n"
msgstr "無法連接到 D-Bus:%s\n"
-#: gio/gapplication-tool.c:288
+#: gio/gapplication-tool.c:286
#, c-format
msgid "error sending %s message to application: %s\n"
msgstr "傳送 %s 訊息到應用程式時發生錯誤:%s\n"
-#: gio/gapplication-tool.c:319
+#: gio/gapplication-tool.c:317
msgid "action name must be given after application id\n"
msgstr "動作名稱必須在應用程式 id 之後\n"
-#: gio/gapplication-tool.c:327
+#: gio/gapplication-tool.c:325
#, c-format
msgid ""
"invalid action name: “%s”\n"
@@ -226,25 +225,25 @@ msgstr ""
"無效的動作名稱:「%s」\n"
"動作名稱必須只由字母、「-」和「.」組成\n"
-#: gio/gapplication-tool.c:346
+#: gio/gapplication-tool.c:344
#, c-format
msgid "error parsing action parameter: %s\n"
msgstr "解析動作參數時發生錯誤:%s\n"
-#: gio/gapplication-tool.c:358
+#: gio/gapplication-tool.c:356
msgid "actions accept a maximum of one parameter\n"
msgstr "動作最大只能接受一個參數\n"
-#: gio/gapplication-tool.c:413
+#: gio/gapplication-tool.c:411
msgid "list-actions command takes only the application id"
msgstr "list-actions 指令只接受應用程式 id"
-#: gio/gapplication-tool.c:423
+#: gio/gapplication-tool.c:421
#, c-format
msgid "unable to find desktop file for application %s\n"
msgstr "無法找到應用程式的桌面檔案 %s\n"
-#: gio/gapplication-tool.c:468
+#: gio/gapplication-tool.c:466
#, c-format
msgid ""
"unrecognised command: %s\n"
@@ -254,8 +253,8 @@ msgstr ""
"\n"
#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498
-#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:646
-#: gio/ginputstream.c:1048 gio/goutputstream.c:223 gio/goutputstream.c:1049
+#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617
+#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049
#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277
#, c-format
msgid "Too large count value passed to %s"
@@ -266,11 +265,11 @@ msgstr "傳給 %s 的計數值太大"
msgid "Seek not supported on base stream"
msgstr "不支援在基礎串流中搜尋"
-#: gio/gbufferedinputstream.c:938
+#: gio/gbufferedinputstream.c:937
msgid "Cannot truncate GBufferedInputStream"
msgstr "不能截短 GBufferedInputStream"
-#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1237 gio/giostream.c:300
+#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300
#: gio/goutputstream.c:2198
msgid "Stream is already closed"
msgstr "串流已經關閉"
@@ -279,7 +278,7 @@ msgstr "串流已經關閉"
msgid "Truncate not supported on base stream"
msgstr "在基礎串流中不支援截短(truncate)"
-#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416
+#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413
#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897
#, c-format
msgid "Operation was cancelled"
@@ -298,23 +297,23 @@ msgid "Not enough space in destination"
msgstr "在目的端中沒有足夠的空間"
#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848
-#: gio/gdatainputstream.c:1266 glib/gconvert.c:448 glib/gconvert.c:878
-#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470
+#: gio/gdatainputstream.c:1261 glib/gconvert.c:448 glib/gconvert.c:878
+#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2461
#: glib/gutf8.c:875 glib/gutf8.c:1328
msgid "Invalid byte sequence in conversion input"
msgstr "轉換輸入資料時遇到不正確的位元組組合"
#: gio/gcharsetconverter.c:347 glib/gconvert.c:456 glib/gconvert.c:792
-#: glib/giochannel.c:1580 glib/giochannel.c:2482
+#: glib/giochannel.c:1571 glib/giochannel.c:2473
#, c-format
msgid "Error during conversion: %s"
msgstr "轉換時發生錯誤:%s"
-#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143
+#: gio/gcharsetconverter.c:445 gio/gsocket.c:1133
msgid "Cancellable initialization not supported"
msgstr "不支援可取消的初始化"
-#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1401
+#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1392
#, c-format
msgid "Conversion from character set “%s” to “%s” is not supported"
msgstr "不支援將字元集「%s」轉換成「%s」"
@@ -324,7 +323,7 @@ msgstr "不支援將字元集「%s」轉換成「%s」"
msgid "Could not open converter from “%s” to “%s”"
msgstr "無法開啟「%s」至「%s」的轉換"
-#: gio/gcontenttype.c:454
+#: gio/gcontenttype.c:452
#, c-format
msgid "%s type"
msgstr "%s 類型"
@@ -362,152 +361,152 @@ msgstr "在這個 OS 無法做到憑證偽裝"
msgid "Unexpected early end-of-stream"
msgstr "未預期的串流過早結束"
-#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322
+#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321
#, c-format
msgid "Unsupported key “%s” in address entry “%s”"
msgstr "「%2$s」位址條目有不支援的「%1$s」鍵"
-#: gio/gdbusaddress.c:172
+#: gio/gdbusaddress.c:171
#, c-format
msgid "Meaningless key/value pair combination in address entry “%s”"
msgstr "在「%s」位址條目中有無意義的鍵/值組合配對"
-#: gio/gdbusaddress.c:181
+#: gio/gdbusaddress.c:180
#, c-format
msgid ""
"Address “%s” is invalid (need exactly one of path, dir, tmpdir, or abstract "
"keys)"
msgstr "「%s」位址無效 (需要有明確的 path、dir、tmpdir 或 abstract 鍵之一)"
-#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274
-#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348
+#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273
+#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347
#, c-format
msgid "Error in address “%s” — the “%s” attribute is malformed"
msgstr "「%s」位址有錯誤 —「%s」特性的格式不良"
-#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682
+#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681
#, c-format
msgid "Unknown or unsupported transport “%s” for address “%s”"
msgstr "「%2$s」位址有不明或不支援的「%1$s」傳輸"
-#: gio/gdbusaddress.c:462
+#: gio/gdbusaddress.c:461
#, c-format
msgid "Address element “%s” does not contain a colon (:)"
msgstr "「%s」位址元素中並未包含分號 (:)"
-#: gio/gdbusaddress.c:471
+#: gio/gdbusaddress.c:470
#, c-format
msgid "Transport name in address element “%s” must not be empty"
msgstr "「%s」位址元素中的傳輸名稱不能空白"
-#: gio/gdbusaddress.c:492
+#: gio/gdbusaddress.c:491
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal "
"sign"
msgstr "在鍵/值配對 %d,「%s」,「%s」位址元素中,並未包含等於符號"
-#: gio/gdbusaddress.c:503
+#: gio/gdbusaddress.c:502
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"
msgstr "在鍵/值配對 %d,「%s」,「%s」位址元素中,不能有空白的鍵"
-#: gio/gdbusaddress.c:517
+#: gio/gdbusaddress.c:516
#, c-format
msgid ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
"“%s”"
msgstr "在鍵/值配對 %d,「%s」,「%s」位址元素中有錯誤的反轉義鍵"
-#: gio/gdbusaddress.c:589
+#: gio/gdbusaddress.c:588
#, c-format
msgid ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
"“path” or “abstract” to be set"
msgstr "「%s」位址有錯誤 — unix 傳輸需要明確的設定一個「path」或「abstract」鍵"
-#: gio/gdbusaddress.c:625
+#: gio/gdbusaddress.c:624
#, c-format
msgid "Error in address “%s” — the host attribute is missing or malformed"
msgstr "「%s」位址有錯誤 — host 特性遺失或格式不良"
-#: gio/gdbusaddress.c:639
+#: gio/gdbusaddress.c:638
#, c-format
msgid "Error in address “%s” — the port attribute is missing or malformed"
msgstr "「%s」位址有錯誤 — port 特性遺失或格式不良"
-#: gio/gdbusaddress.c:653
+#: gio/gdbusaddress.c:652
#, c-format
msgid "Error in address “%s” — the noncefile attribute is missing or malformed"
msgstr "「%s」位址有錯誤 — noncefile 特性遺失或格式不良"
-#: gio/gdbusaddress.c:674
+#: gio/gdbusaddress.c:673
msgid "Error auto-launching: "
msgstr "自動執行失敗:"
-#: gio/gdbusaddress.c:727
+#: gio/gdbusaddress.c:726
#, c-format
msgid "Error opening nonce file “%s”: %s"
msgstr "開啟臨時檔案「%s」時發生錯誤:%s"
-#: gio/gdbusaddress.c:746
+#: gio/gdbusaddress.c:745
#, c-format
msgid "Error reading from nonce file “%s”: %s"
msgstr "讀取臨時檔案「%s」時發生錯誤:%s"
-#: gio/gdbusaddress.c:755
+#: gio/gdbusaddress.c:754
#, c-format
msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d"
msgstr "讀取臨時檔案「%s」時發生錯誤,預期為 16 位元組,卻得到 %d"
-#: gio/gdbusaddress.c:773
+#: gio/gdbusaddress.c:772
#, c-format
msgid "Error writing contents of nonce file “%s” to stream:"
msgstr "寫入臨時檔案「%s」的內容到串流時發生錯誤:"
-#: gio/gdbusaddress.c:988
+#: gio/gdbusaddress.c:981
msgid "The given address is empty"
msgstr "指定的位址是空白的"
-#: gio/gdbusaddress.c:1101
+#: gio/gdbusaddress.c:1094
#, c-format
msgid "Cannot spawn a message bus when setuid"
msgstr "在 setuid 時不能產生訊息匯流排"
-#: gio/gdbusaddress.c:1108
+#: gio/gdbusaddress.c:1101
msgid "Cannot spawn a message bus without a machine-id: "
msgstr "沒有 machine-id 不能產生訊息匯流排:"
-#: gio/gdbusaddress.c:1115
+#: gio/gdbusaddress.c:1108
#, c-format
msgid "Cannot autolaunch D-Bus without X11 $DISPLAY"
msgstr "沒有 X11 $DISPLAY 不能自動執行 D-Bus "
-#: gio/gdbusaddress.c:1157
+#: gio/gdbusaddress.c:1150
#, c-format
msgid "Error spawning command line “%s”: "
msgstr "產生命令列「%s」時出現錯誤:"
-#: gio/gdbusaddress.c:1226
+#: gio/gdbusaddress.c:1219
#, c-format
msgid "Cannot determine session bus address (not implemented for this OS)"
msgstr "不能判斷作業階段匯流排位址(沒有在這個 OS 實作)"
-#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7241
+#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192
#, c-format
msgid ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
"— unknown value “%s”"
msgstr "不能從 DBUS_STARTER_BUS_TYPE 環境變數判斷匯流排位址 — 不明的「%s」值"
-#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7250
+#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201
msgid ""
"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
"variable is not set"
msgstr "不能判斷匯流排位址,因為尚未設定 DBUS_STARTER_BUS_TYPE 環境變數"
-#: gio/gdbusaddress.c:1416
+#: gio/gdbusaddress.c:1376
#, c-format
msgid "Unknown bus type %d"
msgstr "不明的匯流排類型 %d"
@@ -526,232 +525,218 @@ msgid ""
"Exhausted all available authentication mechanisms (tried: %s) (available: %s)"
msgstr "竭盡所有可用的核對機制 (已嘗試:%s) (可用:%s)"
-#: gio/gdbusauth.c:1170
-msgid "User IDs must be the same for peer and server"
-msgstr "對等端和伺服器端的使用者 ID 必須相同"
-
-#: gio/gdbusauth.c:1182
+#: gio/gdbusauth.c:1167
msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
msgstr "已透過 GDBusAuthObserver::authorize-authenticated-peer 取消"
-#: gio/gdbusauthmechanismsha1.c:298
+#: gio/gdbusauthmechanismsha1.c:296
#, c-format
msgid "Error when getting information for directory “%s”: %s"
msgstr "從目錄「%s」取得資訊時發生錯誤:%s"
-#: gio/gdbusauthmechanismsha1.c:313
+#: gio/gdbusauthmechanismsha1.c:311
#, c-format
msgid ""
"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
-msgstr "目錄「%s」的權限格式不良。預期的模式為 0700,卻得到 0%o"
+msgstr "目錄「%s」的權限格式下良。預期的模式為 0700,卻得到 0%o"
-#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357
+#: gio/gdbusauthmechanismsha1.c:341
#, c-format
msgid "Error creating directory “%s”: %s"
msgstr "建立目錄「%s」時發生錯誤:%s"
-#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300
-#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789
-#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049
-#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572
-#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255
-#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243
-#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453
-msgid "Operation not supported"
-msgstr "不支援的操作"
-
-#: gio/gdbusauthmechanismsha1.c:402
+#: gio/gdbusauthmechanismsha1.c:386
#, c-format
msgid "Error opening keyring “%s” for reading: "
msgstr "開啟鑰匙圈「%s」讀取時發生錯誤:"
-#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747
+#: gio/gdbusauthmechanismsha1.c:409 gio/gdbusauthmechanismsha1.c:731
#, c-format
msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "位於「%2$s」內容「%3$s」的鑰匙圈第 %1$d 列格式不良"
-#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761
+#: gio/gdbusauthmechanismsha1.c:423 gio/gdbusauthmechanismsha1.c:745
#, c-format
msgid ""
"First token of line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "位於「%2$s」內容「%3$s」的鑰匙圈第 %1$d 列第一記號格式不良"
-#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775
+#: gio/gdbusauthmechanismsha1.c:437 gio/gdbusauthmechanismsha1.c:759
#, c-format
msgid ""
"Second token of line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "位於「%2$s」內容「%3$s」的鑰匙圈第 %1$d 列第二記號格式不良"
-#: gio/gdbusauthmechanismsha1.c:477
+#: gio/gdbusauthmechanismsha1.c:461
#, c-format
msgid "Didn’t find cookie with id %d in the keyring at “%s”"
msgstr "在「%2$s」鑰匙圈找不到 id %1$d 的 cookie"
-#: gio/gdbusauthmechanismsha1.c:523
+#: gio/gdbusauthmechanismsha1.c:507
#, c-format
msgid "Error creating lock file “%s”: %s"
msgstr "建立鎖定檔案「%s」時發生錯誤:%s"
-#: gio/gdbusauthmechanismsha1.c:587
+#: gio/gdbusauthmechanismsha1.c:571
#, c-format
msgid "Error deleting stale lock file “%s”: %s"
msgstr "刪除舊的鎖定檔案「%s」時發生錯誤:%s"
-#: gio/gdbusauthmechanismsha1.c:626
+#: gio/gdbusauthmechanismsha1.c:610
#, c-format
msgid "Error closing (unlinked) lock file “%s”: %s"
msgstr "關閉 (取消連結) 鎖定檔案時發生錯誤「%s」:%s"
-#: gio/gdbusauthmechanismsha1.c:637
+#: gio/gdbusauthmechanismsha1.c:621
#, c-format
msgid "Error unlinking lock file “%s”: %s"
msgstr "取消連結鎖定檔案時發生錯誤「%s」:%s"
-#: gio/gdbusauthmechanismsha1.c:714
+#: gio/gdbusauthmechanismsha1.c:698
#, c-format
msgid "Error opening keyring “%s” for writing: "
msgstr "開啟鑰匙圈「%s」寫入時發生錯誤:"
-#: gio/gdbusauthmechanismsha1.c:908
+#: gio/gdbusauthmechanismsha1.c:892
#, c-format
msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
msgstr "(另外,釋放「%s」的鎖定失敗:%s)"
-#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2405
+#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391
msgid "The connection is closed"
msgstr "這個連線已關閉"
-#: gio/gdbusconnection.c:1902
+#: gio/gdbusconnection.c:1892
msgid "Timeout was reached"
msgstr "已達逾時時間"
-#: gio/gdbusconnection.c:2528
+#: gio/gdbusconnection.c:2513
msgid ""
"Unsupported flags encountered when constructing a client-side connection"
msgstr "當建立客戶端連線時遇到不支援的旗標"
-#: gio/gdbusconnection.c:4186 gio/gdbusconnection.c:4533
+#: gio/gdbusconnection.c:4163 gio/gdbusconnection.c:4510
#, c-format
msgid ""
"No such interface “org.freedesktop.DBus.Properties” on object at path %s"
msgstr "在 %s 路徑的物件沒有「org.freedesktop.DBus.Properties」這個介面"
-#: gio/gdbusconnection.c:4328
+#: gio/gdbusconnection.c:4305
#, c-format
msgid "No such property “%s”"
msgstr "沒有這個屬性「%s」"
-#: gio/gdbusconnection.c:4340
+#: gio/gdbusconnection.c:4317
#, c-format
msgid "Property “%s” is not readable"
msgstr "無法讀取「%s」屬性"
-#: gio/gdbusconnection.c:4351
+#: gio/gdbusconnection.c:4328
#, c-format
msgid "Property “%s” is not writable"
msgstr "無法寫入「%s」屬性"
-#: gio/gdbusconnection.c:4371
+#: gio/gdbusconnection.c:4348
#, c-format
msgid "Error setting property “%s”: Expected type “%s” but got “%s”"
msgstr "「%s」屬性設定錯誤:預期的類型為「%s」但得到「%s」"
-#: gio/gdbusconnection.c:4476 gio/gdbusconnection.c:4684
-#: gio/gdbusconnection.c:6681
+#: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661
+#: gio/gdbusconnection.c:6632
#, c-format
msgid "No such interface “%s”"
msgstr "沒有這個「%s」介面"
-#: gio/gdbusconnection.c:4902 gio/gdbusconnection.c:7190
+#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141
#, c-format
msgid "No such interface “%s” on object at path %s"
msgstr "在 %2$s 路徑的物件沒有「%1$s」這個介面"
-#: gio/gdbusconnection.c:5000
+#: gio/gdbusconnection.c:4977
#, c-format
msgid "No such method “%s”"
msgstr "沒有「%s」方法"
-#: gio/gdbusconnection.c:5031
+#: gio/gdbusconnection.c:5008
#, c-format
msgid "Type of message, “%s”, does not match expected type “%s”"
msgstr "訊息的類型,「%s」,不符合預期的類型「%s」"
-#: gio/gdbusconnection.c:5229
+#: gio/gdbusconnection.c:5206
#, c-format
msgid "An object is already exported for the interface %s at %s"
msgstr "有物件已為介面 %s 匯出於 %s"
-#: gio/gdbusconnection.c:5455
+#: gio/gdbusconnection.c:5432
#, c-format
msgid "Unable to retrieve property %s.%s"
msgstr "無法取回屬性 %s.%s"
-#: gio/gdbusconnection.c:5511
+#: gio/gdbusconnection.c:5488
#, c-format
msgid "Unable to set property %s.%s"
msgstr "無法設定屬性 %s.%s"
-#: gio/gdbusconnection.c:5690
+#: gio/gdbusconnection.c:5666
#, c-format
msgid "Method “%s” returned type “%s”, but expected “%s”"
msgstr "方法「%s」傳回類型「%s」,但預期為「%s」"
-#: gio/gdbusconnection.c:6792
+#: gio/gdbusconnection.c:6743
#, c-format
msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
msgstr "介面「%2$s」簽章「%3$s」的方法「%1$s」不存在"
-#: gio/gdbusconnection.c:6913
+#: gio/gdbusconnection.c:6864
#, c-format
msgid "A subtree is already exported for %s"
msgstr "子樹狀目錄已為 %s 匯出"
-#: gio/gdbusmessage.c:1266
+#: gio/gdbusmessage.c:1255
msgid "type is INVALID"
msgstr "類型為無效"
-#: gio/gdbusmessage.c:1277
+#: gio/gdbusmessage.c:1266
msgid "METHOD_CALL message: PATH or MEMBER header field is missing"
msgstr "METHOD_CALL 訊息:缺少 PATH 或 MEMBER 標頭欄位"
-#: gio/gdbusmessage.c:1288
+#: gio/gdbusmessage.c:1277
msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing"
msgstr "METHOD_RETURN 訊息:缺少 REPLY_SERIAL 標頭欄位"
-#: gio/gdbusmessage.c:1300
+#: gio/gdbusmessage.c:1289
msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"
msgstr "ERROR 訊息:缺少 REPLY_SERIAL 或 ERROR_NAME 標頭欄位"
-#: gio/gdbusmessage.c:1313
+#: gio/gdbusmessage.c:1302
msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"
msgstr "SIGNAL 訊息:缺少 PATH、INTERFACE 或 MEMBER 標頭欄位"
-#: gio/gdbusmessage.c:1321
+#: gio/gdbusmessage.c:1310
msgid ""
"SIGNAL message: The PATH header field is using the reserved value /org/"
"freedesktop/DBus/Local"
msgstr "SIGNAL 訊息:PATH 標頭欄位使用了保留的值 /org/freedesktop/DBus/Local"
-#: gio/gdbusmessage.c:1329
+#: gio/gdbusmessage.c:1318
msgid ""
"SIGNAL message: The INTERFACE header field is using the reserved value org."
"freedesktop.DBus.Local"
msgstr ""
"SIGNAL 訊息:INTERFACE 標頭欄位使用了保留的值 org.freedesktop.DBus.Local"
-#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437
+#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426
#, c-format
msgid "Wanted to read %lu byte but only got %lu"
msgid_plural "Wanted to read %lu bytes but only got %lu"
msgstr[0] "嘗試讀取 %lu 位元組卻只得到 %lu"
-#: gio/gdbusmessage.c:1391
+#: gio/gdbusmessage.c:1380
#, c-format
msgid "Expected NUL byte after the string “%s” but found byte %d"
msgstr "預期在字串「%s」之後為 NUL 位元組,但是發現位元組 %d"
-#: gio/gdbusmessage.c:1410
+#: gio/gdbusmessage.c:1399
#, c-format
msgid ""
"Expected valid UTF-8 string but found invalid bytes at byte offset %d "
@@ -760,21 +745,21 @@ msgstr ""
"預期為有效的 UTF-8 字串但是在位元組 %d 處發現無效的位元組 (字串的長度為 %d)。"
"到那一點之前的有效 UTF-8 字串為「%s」"
-#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911
+#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900
msgid "Value nested too deeply"
msgstr "值的巢狀層次過深"
-#: gio/gdbusmessage.c:1620
+#: gio/gdbusmessage.c:1609
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus object path"
msgstr "已解析「%s」值不是有效的 D-Bus 物件路徑"
-#: gio/gdbusmessage.c:1642
+#: gio/gdbusmessage.c:1631
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus signature"
msgstr "已解析「%s」值不是一個有效的 D-Bus 簽章"
-#: gio/gdbusmessage.c:1689
+#: gio/gdbusmessage.c:1678
#, c-format
msgid ""
"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)."
@@ -782,7 +767,7 @@ msgid_plural ""
"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."
msgstr[0] "遇到長度為 %u 位元組的陣列。最大長度為 2<<26 位元組 (64 MiB)。"
-#: gio/gdbusmessage.c:1709
+#: gio/gdbusmessage.c:1698
#, c-format
msgid ""
"Encountered array of type “a%c”, expected to have a length a multiple of %u "
@@ -790,115 +775,113 @@ msgid ""
msgstr ""
"遇到類型「a%c」的陣列,預期長度應為 %u 位元組的倍數,但發現長度為 %u 位元組"
-#: gio/gdbusmessage.c:1895
+#: gio/gdbusmessage.c:1884
#, c-format
msgid "Parsed value “%s” for variant is not a valid D-Bus signature"
msgstr "已解析「%s」值不是有效的 D-Bus 簽章"
-#: gio/gdbusmessage.c:1936
+#: gio/gdbusmessage.c:1925
#, c-format
msgid ""
"Error deserializing GVariant with type string “%s” from the D-Bus wire format"
msgstr "從 D-Bus 線性格式以類型字串「%s」反序列化 GVariant 時發生錯誤"
-#: gio/gdbusmessage.c:2121
+#: gio/gdbusmessage.c:2110
#, c-format
msgid ""
"Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value "
"0x%02x"
msgstr "無效的字節順序值。預期為 0x6c (「I」) 或 0x42 (「B」) 卻得到值 0x%02x"
-#: gio/gdbusmessage.c:2134
+#: gio/gdbusmessage.c:2123
#, c-format
msgid "Invalid major protocol version. Expected 1 but found %d"
msgstr "無效的主通訊協定版本。預期為 1 但找到 %d"
-#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784
+#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773
msgid "Signature header found but is not of type signature"
msgstr "找到簽章標頭,但不是一種類型簽章"
-#: gio/gdbusmessage.c:2200
+#: gio/gdbusmessage.c:2189
#, c-format
msgid "Signature header with signature “%s” found but message body is empty"
msgstr "發現簽章「%s」的簽章標頭但訊息主體是空的"
-#: gio/gdbusmessage.c:2215
+#: gio/gdbusmessage.c:2204
#, c-format
msgid "Parsed value “%s” is not a valid D-Bus signature (for body)"
msgstr "已解析「%s」值不是有效的 D-Bus 簽章 (於主體)"
-#: gio/gdbusmessage.c:2247
+#: gio/gdbusmessage.c:2236
#, c-format
msgid "No signature header in message but the message body is %u byte"
msgid_plural "No signature header in message but the message body is %u bytes"
msgstr[0] "在訊息中沒有簽章標頭但訊息主體有 %u 位元組"
-#: gio/gdbusmessage.c:2257
+#: gio/gdbusmessage.c:2246
msgid "Cannot deserialize message: "
msgstr "不能反序列化訊息:"
-#: gio/gdbusmessage.c:2601
+#: gio/gdbusmessage.c:2590
#, c-format
msgid ""
"Error serializing GVariant with type string “%s” to the D-Bus wire format"
msgstr "從 D-Bus 線性格式以類型字串「%s」序列化 GVariant 時發生錯誤"
-#: gio/gdbusmessage.c:2738
+#: gio/gdbusmessage.c:2727
#, c-format
msgid ""
"Number of file descriptors in message (%d) differs from header field (%d)"
msgstr "訊息 (%d) 中的檔案描述狀態數量跟標頭欄位 (%d) 的不同"
-#: gio/gdbusmessage.c:2746
+#: gio/gdbusmessage.c:2735
msgid "Cannot serialize message: "
msgstr "不能序列化訊息:"
-#: gio/gdbusmessage.c:2799
+#: gio/gdbusmessage.c:2788
#, c-format
msgid "Message body has signature “%s” but there is no signature header"
msgstr "訊息主體有簽章「%s」但是沒有簽章標頭"
-#: gio/gdbusmessage.c:2809
+#: gio/gdbusmessage.c:2798
#, c-format
msgid ""
"Message body has type signature “%s” but signature in the header field is "
"“%s”"
msgstr "訊息主體有類型簽章「%s」但是標頭欄位中的簽章為「%s」"
-#: gio/gdbusmessage.c:2825
+#: gio/gdbusmessage.c:2814
#, c-format
msgid "Message body is empty but signature in the header field is “(%s)”"
msgstr "訊息主體是空的但是標頭欄位中的簽章為「%s」"
-#: gio/gdbusmessage.c:3378
+#: gio/gdbusmessage.c:3367
#, c-format
msgid "Error return with body of type “%s”"
msgstr "傳回類型「%s」主體時發生錯誤"
-#: gio/gdbusmessage.c:3386
+#: gio/gdbusmessage.c:3375
msgid "Error return with empty body"
msgstr "傳回空白主體錯誤"
-#: gio/gdbusprivate.c:2246
+#: gio/gdbusprivate.c:2244
#, c-format
msgid "(Type any character to close this window)\n"
msgstr "(輸入任何字元以關閉這個視窗)\n"
-#: gio/gdbusprivate.c:2420
+#: gio/gdbusprivate.c:2418
#, c-format
msgid "Session dbus not running, and autolaunch failed"
msgstr "作業階段 dbus 尚未執行,且自動執行失敗"
-#: gio/gdbusprivate.c:2443
+#: gio/gdbusprivate.c:2441
#, c-format
msgid "Unable to get Hardware profile: %s"
msgstr "無法取得硬體設定檔:%s"
-#. Translators: Both placeholders are file paths
-#: gio/gdbusprivate.c:2494
-#, c-format
-msgid "Unable to load %s or %s: "
-msgstr "無法載入 %s 或 %s︰ "
+#: gio/gdbusprivate.c:2486
+msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
+msgstr "無法載入 /var/lib/dbus/machine-id 或 /etc/machine-id:"
#: gio/gdbusproxy.c:1562
#, c-format
@@ -919,30 +902,30 @@ msgstr ""
"不能呼叫方法;Proxy 是沒有擁有者的 %s 已知名稱,而 Proxy 以 "
"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START 旗標建構"
-#: gio/gdbusserver.c:763
+#: gio/gdbusserver.c:755
msgid "Abstract namespace not supported"
msgstr "不支援抽象命名空間"
-#: gio/gdbusserver.c:856
+#: gio/gdbusserver.c:848
msgid "Cannot specify nonce file when creating a server"
msgstr "當建立伺服器時不能指定臨時檔案"
-#: gio/gdbusserver.c:938
+#: gio/gdbusserver.c:930
#, c-format
msgid "Error writing nonce file at “%s”: %s"
msgstr "在「%s」寫入臨時檔案時發生錯誤:%s"
-#: gio/gdbusserver.c:1113
+#: gio/gdbusserver.c:1103
#, c-format
msgid "The string “%s” is not a valid D-Bus GUID"
msgstr "字串「%s」不是一個有效的 D-Bus GUID"
-#: gio/gdbusserver.c:1153
+#: gio/gdbusserver.c:1143
#, c-format
msgid "Cannot listen on unsupported transport “%s”"
msgstr "不能聽取不支援的傳輸「%s」"
-#: gio/gdbus-tool.c:111
+#: gio/gdbus-tool.c:107
#, c-format
msgid ""
"Commands:\n"
@@ -965,288 +948,283 @@ msgstr ""
" \n"
"使用「%s COMMAND --help」來取得每個指令的求助資訊。\n"
-#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345
-#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236
-#: gio/gdbus-tool.c:1724
+#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336
+#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187
+#: gio/gdbus-tool.c:1672
#, c-format
msgid "Error: %s\n"
msgstr "錯誤:%s\n"
-#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740
+#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688
#, c-format
msgid "Error parsing introspection XML: %s\n"
msgstr "解析檢討 XML 時出現錯誤:%s\n"
-#: gio/gdbus-tool.c:250
+#: gio/gdbus-tool.c:246
#, c-format
msgid "Error: %s is not a valid name\n"
msgstr "錯誤:%s 不是有效的名稱\n"
-#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060
-#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130
-#, c-format
-msgid "Error: %s is not a valid object path\n"
-msgstr "錯誤:%s 不是有效的物件路徑\n"
-
-#: gio/gdbus-tool.c:403
+#: gio/gdbus-tool.c:394
msgid "Connect to the system bus"
msgstr "連線到系統匯流排"
-#: gio/gdbus-tool.c:404
+#: gio/gdbus-tool.c:395
msgid "Connect to the session bus"
msgstr "連線到作業階段匯流排"
-#: gio/gdbus-tool.c:405
+#: gio/gdbus-tool.c:396
msgid "Connect to given D-Bus address"
msgstr "連線到指定的 D-Bus 位址"
-#: gio/gdbus-tool.c:415
+#: gio/gdbus-tool.c:406
msgid "Connection Endpoint Options:"
msgstr "連線端點選項:"
-#: gio/gdbus-tool.c:416
+#: gio/gdbus-tool.c:407
msgid "Options specifying the connection endpoint"
msgstr "指定連線端點的選項"
-#: gio/gdbus-tool.c:439
+#: gio/gdbus-tool.c:430
#, c-format
msgid "No connection endpoint specified"
msgstr "沒有指定連線端點"
-#: gio/gdbus-tool.c:449
+#: gio/gdbus-tool.c:440
#, c-format
msgid "Multiple connection endpoints specified"
msgstr "指定了多重連線端點"
-#: gio/gdbus-tool.c:522
+#: gio/gdbus-tool.c:513
#, c-format
msgid ""
"Warning: According to introspection data, interface “%s” does not exist\n"
msgstr "警告:根據檢討資料,介面「%s」不存在\n"
-#: gio/gdbus-tool.c:531
+#: gio/gdbus-tool.c:522
#, c-format
msgid ""
"Warning: According to introspection data, method “%s” does not exist on "
"interface “%s”\n"
msgstr "警告:根據檢討資料,介面「%2$s」的方法「%1$s」不存在\n"
-#: gio/gdbus-tool.c:593
+#: gio/gdbus-tool.c:584
msgid "Optional destination for signal (unique name)"
msgstr "信號的選擇性目的端 (獨特名稱)"
-#: gio/gdbus-tool.c:594
+#: gio/gdbus-tool.c:585
msgid "Object path to emit signal on"
msgstr "要發出信號的物件路徑"
-#: gio/gdbus-tool.c:595
+#: gio/gdbus-tool.c:586
msgid "Signal and interface name"
msgstr "信號和介面名稱"
-#: gio/gdbus-tool.c:628
+#: gio/gdbus-tool.c:619
msgid "Emit a signal."
msgstr "發出信號。"
-#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827
-#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279
+#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775
+#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227
#, c-format
msgid "Error connecting: %s\n"
msgstr "連線錯誤:%s\n"
-#: gio/gdbus-tool.c:703
+#: gio/gdbus-tool.c:694
#, c-format
msgid "Error: %s is not a valid unique bus name.\n"
msgstr "錯誤:%s 不是有效的獨特匯流排名稱。\n"
-#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870
+#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818
msgid "Error: Object path is not specified\n"
msgstr "錯誤:沒有指定物件路徑\n"
-#: gio/gdbus-tool.c:765
+#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838
+#: gio/gdbus-tool.c:2078
+#, c-format
+msgid "Error: %s is not a valid object path\n"
+msgstr "錯誤:%s 不是有效的物件路徑\n"
+
+#: gio/gdbus-tool.c:756
msgid "Error: Signal name is not specified\n"
msgstr "錯誤:沒有指定信號名稱\n"
-#: gio/gdbus-tool.c:779
+#: gio/gdbus-tool.c:770
#, c-format
msgid "Error: Signal name “%s” is invalid\n"
msgstr "錯誤:「%s」信號名稱無效\n"
-#: gio/gdbus-tool.c:791
+#: gio/gdbus-tool.c:782
#, c-format
msgid "Error: %s is not a valid interface name\n"
msgstr "錯誤:%s 不是有效的介面名稱\n"
-#: gio/gdbus-tool.c:797
+#: gio/gdbus-tool.c:788
#, c-format
msgid "Error: %s is not a valid member name\n"
msgstr "錯誤:%s 不是有效的成員名稱\n"
#. Use the original non-"parse-me-harder" error
-#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172
+#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156
#, c-format
msgid "Error parsing parameter %d: %s\n"
msgstr "解析參數 %d 時發生錯誤:%s\n"
-#: gio/gdbus-tool.c:866
+#: gio/gdbus-tool.c:857
#, c-format
msgid "Error flushing connection: %s\n"
msgstr "清除連線時發生錯誤:%s\n"
-#: gio/gdbus-tool.c:893
+#: gio/gdbus-tool.c:884
msgid "Destination name to invoke method on"
msgstr "要呼叫方法的目的端名稱"
-#: gio/gdbus-tool.c:894
+#: gio/gdbus-tool.c:885
msgid "Object path to invoke method on"
msgstr "要呼叫方法的物件路徑"
-#: gio/gdbus-tool.c:895
+#: gio/gdbus-tool.c:886
msgid "Method and interface name"
msgstr "方法和介面名稱"
-#: gio/gdbus-tool.c:896
+#: gio/gdbus-tool.c:887
msgid "Timeout in seconds"
msgstr "逾時時間(秒)"
-#: gio/gdbus-tool.c:942
+#: gio/gdbus-tool.c:926
msgid "Invoke a method on a remote object."
msgstr "呼叫遠端物件的方法。"
-#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084
+#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032
msgid "Error: Destination is not specified\n"
msgstr "錯誤:尚未指定目的端\n"
-#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095
+#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043
#, c-format
msgid "Error: %s is not a valid bus name\n"
msgstr "錯誤:%s 不是有效的匯流排名稱\n"
-#: gio/gdbus-tool.c:1075
+#: gio/gdbus-tool.c:1059
msgid "Error: Method name is not specified\n"
msgstr "錯誤:沒有指定方法名稱\n"
-#: gio/gdbus-tool.c:1086
+#: gio/gdbus-tool.c:1070
#, c-format
msgid "Error: Method name “%s” is invalid\n"
msgstr "錯誤:方法名稱「%s」是無效的\n"
-#: gio/gdbus-tool.c:1164
+#: gio/gdbus-tool.c:1148
#, c-format
msgid "Error parsing parameter %d of type “%s”: %s\n"
msgstr "解析類型「%2$s」的參數 %1$d 時發生錯誤:%3$s\n"
-#: gio/gdbus-tool.c:1190
-#, c-format
-msgid "Error adding handle %d: %s\n"
-msgstr "加入處理程式 %d 時發生錯誤:%s\n"
-
-#: gio/gdbus-tool.c:1686
+#: gio/gdbus-tool.c:1634
msgid "Destination name to introspect"
msgstr "要檢討的目的端名稱"
-#: gio/gdbus-tool.c:1687
+#: gio/gdbus-tool.c:1635
msgid "Object path to introspect"
msgstr "要檢討的物件路徑"
-#: gio/gdbus-tool.c:1688
+#: gio/gdbus-tool.c:1636
msgid "Print XML"
msgstr "顯示 XML"
-#: gio/gdbus-tool.c:1689
+#: gio/gdbus-tool.c:1637
msgid "Introspect children"
msgstr "Introspect 子項目"
-#: gio/gdbus-tool.c:1690
+#: gio/gdbus-tool.c:1638
msgid "Only print properties"
msgstr "只有列印特性"
-#: gio/gdbus-tool.c:1779
+#: gio/gdbus-tool.c:1727
msgid "Introspect a remote object."
msgstr "檢查遠端物件。"
-#: gio/gdbus-tool.c:1985
+#: gio/gdbus-tool.c:1933
msgid "Destination name to monitor"
msgstr "要監控的目的端名稱"
-#: gio/gdbus-tool.c:1986
+#: gio/gdbus-tool.c:1934
msgid "Object path to monitor"
msgstr "要監控的物件路徑"
-#: gio/gdbus-tool.c:2011
+#: gio/gdbus-tool.c:1959
msgid "Monitor a remote object."
msgstr "監控遠端物件。"
-#: gio/gdbus-tool.c:2069
+#: gio/gdbus-tool.c:2017
msgid "Error: can’t monitor a non-message-bus connection\n"
msgstr "錯誤:無法監控非訊息匯流排的連線\n"
-#: gio/gdbus-tool.c:2193
+#: gio/gdbus-tool.c:2141
msgid "Service to activate before waiting for the other one (well-known name)"
msgstr "在等待其他前要啟用的服務(已知名稱)"
-#: gio/gdbus-tool.c:2196
+#: gio/gdbus-tool.c:2144
msgid ""
"Timeout to wait for before exiting with an error (seconds); 0 for no timeout "
"(default)"
msgstr "發生錯誤結束前的等待逾時(秒);0 表示沒有逾時(預設值)"
-#: gio/gdbus-tool.c:2244
+#: gio/gdbus-tool.c:2192
msgid "[OPTION…] BUS-NAME"
msgstr "[OPTION…] BUS-NAME"
-#: gio/gdbus-tool.c:2245
+#: gio/gdbus-tool.c:2193
msgid "Wait for a bus name to appear."
msgstr "等待匯流排名稱顯示。"
-#: gio/gdbus-tool.c:2321
+#: gio/gdbus-tool.c:2269
msgid "Error: A service to activate for must be specified.\n"
msgstr "錯誤:需要指定要啟用的服務。\n"
-#: gio/gdbus-tool.c:2326
+#: gio/gdbus-tool.c:2274
msgid "Error: A service to wait for must be specified.\n"
msgstr "錯誤:需要指定要等待的服務。\n"
-#: gio/gdbus-tool.c:2331
+#: gio/gdbus-tool.c:2279
msgid "Error: Too many arguments.\n"
msgstr "錯誤:引數太多。\n"
-#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346
+#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294
#, c-format
msgid "Error: %s is not a valid well-known bus name.\n"
msgstr "錯誤:%s 不是有效的已知匯流排名稱。\n"
-#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932
+#: gio/gdesktopappinfo.c:2073 gio/gdesktopappinfo.c:4893
msgid "Unnamed"
msgstr "未命名的"
-#: gio/gdesktopappinfo.c:2516
+#: gio/gdesktopappinfo.c:2483
msgid "Desktop file didn’t specify Exec field"
msgstr "桌面(Desktop)檔案未指定 Exec 欄位"
-#: gio/gdesktopappinfo.c:2801
+#: gio/gdesktopappinfo.c:2763
msgid "Unable to find terminal required for application"
msgstr "無法找到應用程式要求的終端機"
-#: gio/gdesktopappinfo.c:3452
+#: gio/gdesktopappinfo.c:3414
#, c-format
msgid "Can’t create user application configuration folder %s: %s"
msgstr "不能建立使用者應用程式設定資料夾 %s:%s"
-#: gio/gdesktopappinfo.c:3456
+#: gio/gdesktopappinfo.c:3418
#, c-format
msgid "Can’t create user MIME configuration folder %s: %s"
msgstr "不能建立使用者 MIME 設定資料夾 %s:%s"
-#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722
+#: gio/gdesktopappinfo.c:3660 gio/gdesktopappinfo.c:3684
msgid "Application information lacks an identifier"
msgstr "應用程式資訊缺少識別碼"
-#: gio/gdesktopappinfo.c:3958
+#: gio/gdesktopappinfo.c:3920
#, c-format
msgid "Can’t create user desktop file %s"
msgstr "不能建立使用者桌面檔案 %s"
-#: gio/gdesktopappinfo.c:4094
+#: gio/gdesktopappinfo.c:4056
#, c-format
msgid "Custom definition for %s"
msgstr "自訂 %s 的定義"
@@ -1311,77 +1289,87 @@ msgstr "GEmblemedIcon 編碼中記號 (%d) 的數量格式不正確"
msgid "Expected a GEmblem for GEmblemedIcon"
msgstr "預期為 GEmblemedIcon 的 GEmblem"
+#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658
+#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912
+#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777
+#: gio/gfile.c:4070 gio/gfile.c:4540 gio/gfile.c:4951 gio/gfile.c:5036
+#: gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 gio/gfile.c:5411
+#: gio/gfile.c:8121 gio/gfile.c:8211 gio/gfile.c:8295
+#: gio/win32/gwinhttpfile.c:453
+msgid "Operation not supported"
+msgstr "不支援的操作"
+
#. Translators: This is an error message when
#. * trying to find the enclosing (user visible)
#. * mount of a file, but none exists.
#.
-#: gio/gfile.c:1561
+#: gio/gfile.c:1543
msgid "Containing mount does not exist"
msgstr "包含了不存在的掛載點"
-#: gio/gfile.c:2608 gio/glocalfile.c:2472
+#: gio/gfile.c:2590 gio/glocalfile.c:2430
msgid "Can’t copy over directory"
msgstr "不能複製整個目錄"
-#: gio/gfile.c:2668
+#: gio/gfile.c:2650
msgid "Can’t copy directory over directory"
msgstr "不能將目錄複製到目錄上"
-#: gio/gfile.c:2676
+#: gio/gfile.c:2658
msgid "Target file exists"
msgstr "目標檔案已存在"
-#: gio/gfile.c:2695
+#: gio/gfile.c:2677
msgid "Can’t recursively copy directory"
msgstr "不能遞廻複製目錄"
-#: gio/gfile.c:2996
+#: gio/gfile.c:2952
msgid "Splice not supported"
msgstr "不支援拼接"
-#: gio/gfile.c:3000
+#: gio/gfile.c:2956 gio/gfile.c:3001
#, c-format
msgid "Error splicing file: %s"
msgstr "拼接檔案時發生錯誤:%s"
-#: gio/gfile.c:3152
+#: gio/gfile.c:3117
msgid "Copy (reflink/clone) between mounts is not supported"
msgstr "不支援在掛載點之間複製 (參照連結/重製)"
-#: gio/gfile.c:3156
+#: gio/gfile.c:3121
msgid "Copy (reflink/clone) is not supported or invalid"
msgstr "複製 (參照連結/重製) 不支援或無效"
-#: gio/gfile.c:3161
+#: gio/gfile.c:3126
msgid "Copy (reflink/clone) is not supported or didn’t work"
msgstr "複製 (參照連結/重製) 不支援或無法運作"
-#: gio/gfile.c:3226
+#: gio/gfile.c:3190
msgid "Can’t copy special file"
msgstr "不能複製特殊的檔案"
-#: gio/gfile.c:4035
+#: gio/gfile.c:4003
msgid "Invalid symlink value given"
msgstr "提供了無效的符號連結值"
-#: gio/gfile.c:4045 glib/gfileutils.c:2362
+#: gio/gfile.c:4013 glib/gfileutils.c:2349
msgid "Symbolic links not supported"
msgstr "不支援符號連結"
-#: gio/gfile.c:4213
+#: gio/gfile.c:4181
msgid "Trash not supported"
msgstr "不支援垃圾桶"
-#: gio/gfile.c:4325
+#: gio/gfile.c:4293
#, c-format
msgid "File names cannot contain “%c”"
msgstr "檔案名稱不能包含「%c」"
-#: gio/gfile.c:6806 gio/gvolume.c:364
+#: gio/gfile.c:6774 gio/gvolume.c:364
msgid "volume doesn’t implement mount"
msgstr "儲存區尚未實作掛載功能"
-#: gio/gfile.c:6920 gio/gfile.c:6968
+#: gio/gfile.c:6888 gio/gfile.c:6936
msgid "No application is registered as handling this file"
msgstr "沒有應用程式註冊為用以處理這個檔案"
@@ -1398,12 +1386,12 @@ msgstr "檔案列舉器(enumerator)有異常操作"
msgid "File enumerator is already closed"
msgstr "檔案列舉器(enumerator)已經關閉"
-#: gio/gfileicon.c:250
+#: gio/gfileicon.c:236
#, c-format
msgid "Can’t handle version %d of GFileIcon encoding"
msgstr "不能處理版本為 %d 的 GFileIcon 編碼"
-#: gio/gfileicon.c:260
+#: gio/gfileicon.c:246
msgid "Malformed input data for GFileIcon"
msgstr "給 GFileIcon 的輸入資料格式不良"
@@ -1452,11 +1440,7 @@ msgstr "HTTP 代理伺服器需要核對"
msgid "HTTP proxy connection failed: %i"
msgstr "HTTP 代理伺服器連線失敗:%i"
-#: gio/ghttpproxy.c:266
-msgid "HTTP proxy response too big"
-msgstr "HTTP 代理伺服器回應太大"
-
-#: gio/ghttpproxy.c:283
+#: gio/ghttpproxy.c:269
msgid "HTTP proxy server closed connection unexpectedly."
msgstr "HTTP 代理伺服器未預期關閉連線。"
@@ -1531,7 +1515,7 @@ msgstr "輸入串流尚未實作讀取"
#. Translators: This is an error you get if there is
#. * already an operation running against this stream when
#. * you try to start one
-#: gio/ginputstream.c:1247 gio/giostream.c:310 gio/goutputstream.c:2208
+#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208
msgid "Stream has outstanding operation"
msgstr "串流有異常操作"
@@ -1572,62 +1556,58 @@ msgid "Show information about locations"
msgstr "顯示位置的相關資訊"
#: gio/gio-tool.c:232
-msgid "Launch an application from a desktop file"
-msgstr "從 .desktop 檔案執行應用程式"
-
-#: gio/gio-tool.c:233
msgid "List the contents of locations"
msgstr "列出位置的內容"
-#: gio/gio-tool.c:234
+#: gio/gio-tool.c:233
msgid "Get or set the handler for a mimetype"
msgstr "取得或設定 MIME 類型的處理程式"
-#: gio/gio-tool.c:235
+#: gio/gio-tool.c:234
msgid "Create directories"
msgstr "建立目錄"
-#: gio/gio-tool.c:236
+#: gio/gio-tool.c:235
msgid "Monitor files and directories for changes"
msgstr "監控檔案與目錄的變更"
-#: gio/gio-tool.c:237
+#: gio/gio-tool.c:236
msgid "Mount or unmount the locations"
msgstr "掛載或卸載位置"
-#: gio/gio-tool.c:238
+#: gio/gio-tool.c:237
msgid "Move one or more files"
msgstr "移動一個或多個檔案"
-#: gio/gio-tool.c:239
+#: gio/gio-tool.c:238
msgid "Open files with the default application"
msgstr "以預設的應用程式開啟檔案"
-#: gio/gio-tool.c:240
+#: gio/gio-tool.c:239
msgid "Rename a file"
msgstr "重新命名檔案"
-#: gio/gio-tool.c:241
+#: gio/gio-tool.c:240
msgid "Delete one or more files"
msgstr "刪除一個或多個檔案"
-#: gio/gio-tool.c:242
+#: gio/gio-tool.c:241
msgid "Read from standard input and save"
msgstr "從標準輸入讀取並儲存"
-#: gio/gio-tool.c:243
+#: gio/gio-tool.c:242
msgid "Set a file attribute"
msgstr "設定檔案特性"
-#: gio/gio-tool.c:244
+#: gio/gio-tool.c:243
msgid "Move files or directories to the trash"
msgstr "將檔案或目錄移至垃圾桶"
-#: gio/gio-tool.c:245
+#: gio/gio-tool.c:244
msgid "Lists the contents of locations in a tree"
msgstr "以樹狀圖列出位置的內容"
-#: gio/gio-tool.c:247
+#: gio/gio-tool.c:246
#, c-format
msgid "Use %s to get detailed help.\n"
msgstr "使用 %s 以取得詳細的求助。\n"
@@ -1637,12 +1617,12 @@ msgid "Error writing to stdout"
msgstr "寫入至標準輸出時發生錯誤"
#. Translators: commandline placeholder
-#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172
+#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:333 gio/gio-tool-list.c:172
#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39
#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43
-#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
+#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70
#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89
-#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239
+#: gio/gio-tool-trash.c:90 gio/gio-tool-tree.c:239
msgid "LOCATION"
msgstr "LOCATION"
@@ -1660,9 +1640,9 @@ msgstr ""
"位置來取代本地端檔案:例如您可以使用類似\n"
" smb://server/resource/file.txt 做為位置。"
-#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76
-#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
-#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303
+#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76
+#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96
+#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:145
msgid "No locations given"
msgstr "未提供位置"
@@ -1797,24 +1777,24 @@ msgstr "uri: %s\n"
msgid "local path: %s\n"
msgstr "本機路徑:%s\n"
-#: gio/gio-tool-info.c:205
+#: gio/gio-tool-info.c:199
#, c-format
msgid "unix mount: %s%s %s %s %s\n"
msgstr "unix 掛載:%s%s %s %s %s\n"
-#: gio/gio-tool-info.c:286
+#: gio/gio-tool-info.c:279
msgid "Settable attributes:\n"
msgstr "可設定特性:\n"
-#: gio/gio-tool-info.c:310
+#: gio/gio-tool-info.c:303
msgid "Writable attribute namespaces:\n"
msgstr "可寫入特性命名空間:\n"
-#: gio/gio-tool-info.c:345
+#: gio/gio-tool-info.c:338
msgid "Show information about locations."
msgstr "顯示位置的相關資訊。"
-#: gio/gio-tool-info.c:347
+#: gio/gio-tool-info.c:340
msgid ""
"gio info is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -1828,40 +1808,6 @@ msgstr ""
"特性可以使用它們的 GIO 名稱來指定,如 standard::icon\n"
"或只使用命名空間,像 unix,或「*」比對所有的屬性"
-#. Translators: commandline placeholder
-#: gio/gio-tool-launch.c:54
-msgid "DESKTOP-FILE [FILE-ARG …]"
-msgstr "DESKTOP-檔案 [檔案-引數 …]"
-
-#: gio/gio-tool-launch.c:57
-msgid ""
-"Launch an application from a desktop file, passing optional filename "
-"arguments to it."
-msgstr "從桌面檔案啟動應用程式,可以將選擇性的檔案名稱引數傳遞給它。"
-
-#: gio/gio-tool-launch.c:77
-msgid "No desktop file given"
-msgstr "沒有提供桌面檔案"
-
-#: gio/gio-tool-launch.c:85
-msgid "The launch command is not currently supported on this platform"
-msgstr "您的平臺目前沒有支援啟動指令"
-
-#: gio/gio-tool-launch.c:98
-#, c-format
-msgid "Unable to load ‘%s‘: %s"
-msgstr "無法載入 ‘%s‘ ︰%s"
-
-#: gio/gio-tool-launch.c:107
-#, c-format
-msgid "Unable to load application information for ‘%s‘"
-msgstr "無法載入‘%s‘的應用程式資訊"
-
-#: gio/gio-tool-launch.c:119
-#, c-format
-msgid "Unable to launch application ‘%s’: %s"
-msgstr "無法啟動應用程式‘%s’︰%s"
-
#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32
msgid "Show hidden files"
msgstr "顯示隱藏檔案"
@@ -1999,7 +1945,7 @@ msgstr "回報移動與重新命名為簡單的刪除/建立事件"
msgid "Watch for mount events"
msgstr "監看掛載事件"
-#: gio/gio-tool-monitor.c:209
+#: gio/gio-tool-monitor.c:208
msgid "Monitor files or directories for changes."
msgstr "監控檔案或目錄的變更。"
@@ -2123,7 +2069,7 @@ msgstr ""
"使用註冊為處理該檔案類型的\n"
"預設應用程式來開啟檔案。"
-#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33
+#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31
msgid "Ignore nonexistent files, never prompt"
msgstr "忽略不存在的檔案,永不提示"
@@ -2236,47 +2182,13 @@ msgstr "尚未指定值"
msgid "Invalid attribute type “%s”"
msgstr "無效的特性類型「%s」"
-#: gio/gio-tool-trash.c:34
+#: gio/gio-tool-trash.c:32
msgid "Empty the trash"
msgstr "清理垃圾桶"
-#: gio/gio-tool-trash.c:35
-msgid "List files in the trash with their original locations"
-msgstr "列出回收筒中的檔案與它們原始的位置"
-
-#: gio/gio-tool-trash.c:36
-msgid ""
-"Restore a file from trash to its original location (possibly recreating the "
-"directory)"
-msgstr "將檔案從回收筒還原到其原始位置 (可能會重新建立目錄)"
-
-#: gio/gio-tool-trash.c:106
-msgid "Unable to find original path"
-msgstr "無法找到原始的路徑"
-
-#: gio/gio-tool-trash.c:123
-msgid "Unable to recreate original location: "
-msgstr "無法建立原始位置︰ "
-
-#: gio/gio-tool-trash.c:136
-msgid "Unable to move file to its original location: "
-msgstr "無法將檔案移至其原始位置: "
-
-#: gio/gio-tool-trash.c:225
-msgid "Move/Restore files or directories to the trash."
-msgstr "將檔案或目錄移動/復原至回收筒。"
-
-#: gio/gio-tool-trash.c:227
-msgid ""
-"Note: for --restore switch, if the original location of the trashed file \n"
-"already exists, it will not be overwritten unless --force is set."
-msgstr ""
-"注意:以 --restore 開關而言,如果回收筒中檔案的原始位置 \n"
-"已經存在,它將不會被覆蓋,除非設定 --force。"
-
-#: gio/gio-tool-trash.c:258
-msgid "Location given doesn't start with trash:///"
-msgstr "指定的的位置不是以 trash:/// 開頭"
+#: gio/gio-tool-trash.c:95
+msgid "Move files or directories to the trash."
+msgstr "將檔案或目錄移至垃圾桶。"
#: gio/gio-tool-tree.c:33
msgid "Follow symbolic links, mounts and shortcuts"
@@ -2910,8 +2822,8 @@ msgstr "讀取檔案 %s 時發生錯誤:%s"
msgid "Can’t rename file, filename already exists"
msgstr "不能重新命名檔案,該檔案名稱已存在"
-#: gio/glocalfile.c:1182 gio/glocalfile.c:2366 gio/glocalfile.c:2394
-#: gio/glocalfile.c:2533 gio/glocalfileoutputstream.c:656
+#: gio/glocalfile.c:1182 gio/glocalfile.c:2324 gio/glocalfile.c:2352
+#: gio/glocalfile.c:2491 gio/glocalfileoutputstream.c:650
msgid "Invalid filename"
msgstr "無效的檔案名稱"
@@ -2925,91 +2837,91 @@ msgstr "開啟檔案 %s 時發生錯誤:%s"
msgid "Error removing file %s: %s"
msgstr "移除檔案 %s 時發生錯誤:%s"
-#: gio/glocalfile.c:1980 gio/glocalfile.c:1991
+#: gio/glocalfile.c:1969
#, c-format
msgid "Error trashing file %s: %s"
msgstr "移動檔案 %s 至垃圾桶時發生錯誤:%s"
-#: gio/glocalfile.c:2029
+#: gio/glocalfile.c:2010
#, c-format
-msgid "Unable to create trash directory %s: %s"
-msgstr "無法建立回收筒目錄 %s:%s"
+msgid "Unable to create trash dir %s: %s"
+msgstr "無法建立垃圾桶目錄 %s:%s"
-#: gio/glocalfile.c:2050
+#: gio/glocalfile.c:2030
#, c-format
msgid "Unable to find toplevel directory to trash %s"
msgstr "無法找到垃圾桶 %s 的頂端層級目錄"
-#: gio/glocalfile.c:2058
+#: gio/glocalfile.c:2038
#, c-format
msgid "Trashing on system internal mounts is not supported"
msgstr "不支援在系統內部掛載點使用垃圾桶"
-#: gio/glocalfile.c:2141 gio/glocalfile.c:2169
+#: gio/glocalfile.c:2118 gio/glocalfile.c:2138
#, c-format
-msgid "Unable to find or create trash directory %s to trash %s"
-msgstr "無法找到或建立回收筒目錄 %s 以回收 %s"
+msgid "Unable to find or create trash directory for %s"
+msgstr "無法找到或建立 %s 的垃圾桶目錄"
-#: gio/glocalfile.c:2215
+#: gio/glocalfile.c:2173
#, c-format
msgid "Unable to create trashing info file for %s: %s"
msgstr "無法建立 %s 垃圾桶資訊檔案:%s"
-#: gio/glocalfile.c:2277
+#: gio/glocalfile.c:2235
#, c-format
msgid "Unable to trash file %s across filesystem boundaries"
msgstr "無法將檔案 %s 跨檔案系統邊界移至垃圾桶"
-#: gio/glocalfile.c:2281 gio/glocalfile.c:2337
+#: gio/glocalfile.c:2239 gio/glocalfile.c:2295
#, c-format
msgid "Unable to trash file %s: %s"
msgstr "無法將檔案 %s 移至垃圾桶:%s"
-#: gio/glocalfile.c:2343
+#: gio/glocalfile.c:2301
#, c-format
msgid "Unable to trash file %s"
msgstr "無法將檔案 %s 移至垃圾桶"
-#: gio/glocalfile.c:2369
+#: gio/glocalfile.c:2327
#, c-format
msgid "Error creating directory %s: %s"
msgstr "建立目錄 %s 時發生錯誤:%s"
-#: gio/glocalfile.c:2398
+#: gio/glocalfile.c:2356
#, c-format
msgid "Filesystem does not support symbolic links"
msgstr "檔案系統不支援符號連結"
-#: gio/glocalfile.c:2401
+#: gio/glocalfile.c:2359
#, c-format
msgid "Error making symbolic link %s: %s"
msgstr "建立符號連結 %s 時發生錯誤:%s"
-#: gio/glocalfile.c:2444 gio/glocalfile.c:2479 gio/glocalfile.c:2536
+#: gio/glocalfile.c:2402 gio/glocalfile.c:2437 gio/glocalfile.c:2494
#, c-format
msgid "Error moving file %s: %s"
msgstr "移動檔案 %s 時發生錯誤:%s"
-#: gio/glocalfile.c:2467
+#: gio/glocalfile.c:2425
msgid "Can’t move directory over directory"
msgstr "不能將目錄移動至目錄上"
-#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1079
-#: gio/glocalfileoutputstream.c:1093 gio/glocalfileoutputstream.c:1108
-#: gio/glocalfileoutputstream.c:1125 gio/glocalfileoutputstream.c:1139
+#: gio/glocalfile.c:2451 gio/glocalfileoutputstream.c:1039
+#: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068
+#: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099
msgid "Backup file creation failed"
msgstr "建立備份檔案失敗"
-#: gio/glocalfile.c:2512
+#: gio/glocalfile.c:2470
#, c-format
msgid "Error removing target file: %s"
msgstr "移除目標檔案時發生錯誤:%s"
-#: gio/glocalfile.c:2526
+#: gio/glocalfile.c:2484
msgid "Move between mounts not supported"
msgstr "不支援在掛載點之間移動"
-#: gio/glocalfile.c:2700
+#: gio/glocalfile.c:2658
#, c-format
msgid "Could not determine the disk usage of %s: %s"
msgstr "無法決定 %s 的磁碟使用量:%s"
@@ -3031,184 +2943,185 @@ msgstr "無效的延伸特性名稱"
msgid "Error setting extended attribute “%s”: %s"
msgstr "設定延伸特性「%s」時發生錯誤:%s"
-#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191
+#: gio/glocalfileinfo.c:1666 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
msgstr "(無效的編碼)"
-#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943
+#: gio/glocalfileinfo.c:1825 gio/glocalfileoutputstream.c:915
#, c-format
msgid "Error when getting information for file “%s”: %s"
msgstr "取得檔案「%s」資訊時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2134
+#: gio/glocalfileinfo.c:2091
#, c-format
msgid "Error when getting information for file descriptor: %s"
msgstr "取得檔案描述狀態資訊時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2179
+#: gio/glocalfileinfo.c:2136
msgid "Invalid attribute type (uint32 expected)"
msgstr "無效的特性類型(應為 uint32 值)"
-#: gio/glocalfileinfo.c:2197
+#: gio/glocalfileinfo.c:2154
msgid "Invalid attribute type (uint64 expected)"
msgstr "無效的特性類型(應為 uint64 值)"
-#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235
+#: gio/glocalfileinfo.c:2173 gio/glocalfileinfo.c:2192
msgid "Invalid attribute type (byte string expected)"
msgstr "無效的特性類型(應為 byte string 值)"
-#: gio/glocalfileinfo.c:2282
+#: gio/glocalfileinfo.c:2239
msgid "Cannot set permissions on symlinks"
msgstr "不能設定符號連結的權限"
-#: gio/glocalfileinfo.c:2298
+#: gio/glocalfileinfo.c:2255
#, c-format
msgid "Error setting permissions: %s"
msgstr "設定權限時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2349
+#: gio/glocalfileinfo.c:2306
#, c-format
msgid "Error setting owner: %s"
msgstr "設定擁有者時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2372
+#: gio/glocalfileinfo.c:2329
msgid "symlink must be non-NULL"
msgstr "符號連結必須為非-NULL"
-#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401
-#: gio/glocalfileinfo.c:2412
+#: gio/glocalfileinfo.c:2339 gio/glocalfileinfo.c:2358
+#: gio/glocalfileinfo.c:2369
#, c-format
msgid "Error setting symlink: %s"
msgstr "設定符號連結時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2391
+#: gio/glocalfileinfo.c:2348
msgid "Error setting symlink: file is not a symlink"
msgstr "設定符號連結時發生錯誤:檔案不是符號連結"
-#: gio/glocalfileinfo.c:2463
+#: gio/glocalfileinfo.c:2420
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
msgstr "UNIX 時間戳 %2$lld 的延伸奈秒 %1$d 是負數"
-#: gio/glocalfileinfo.c:2472
+#: gio/glocalfileinfo.c:2429
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
msgstr "UNIX 時間戳 %2$lld 的延伸奈秒 %1$d 達 1 秒"
-#: gio/glocalfileinfo.c:2482
+#: gio/glocalfileinfo.c:2439
#, c-format
msgid "UNIX timestamp %lld does not fit into 64 bits"
msgstr "UNIX 時間戳 %lld 不能完整放入 64 位元"
-#: gio/glocalfileinfo.c:2493
+#: gio/glocalfileinfo.c:2450
#, c-format
msgid "UNIX timestamp %lld is outside of the range supported by Windows"
msgstr "UNIX 時間戳 %lld 超出 Windows 所支援的範圍"
-#: gio/glocalfileinfo.c:2557
+#: gio/glocalfileinfo.c:2514
#, c-format
msgid "File name “%s” cannot be converted to UTF-16"
msgstr "「%s」檔名無法轉換為 UTF-16"
-#: gio/glocalfileinfo.c:2576
+#: gio/glocalfileinfo.c:2533
#, c-format
msgid "File “%s” cannot be opened: Windows Error %lu"
msgstr "無法開啟「%s」檔案:Windows 錯誤 %lu"
-#: gio/glocalfileinfo.c:2589
+#: gio/glocalfileinfo.c:2546
#, c-format
msgid "Error setting modification or access time for file “%s”: %lu"
msgstr "設定「%s」檔案的修改或存取時間時發生錯誤:%lu"
-#: gio/glocalfileinfo.c:2690
+#: gio/glocalfileinfo.c:2647
#, c-format
msgid "Error setting modification or access time: %s"
msgstr "設定修改或存取時刻時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2713
+#: gio/glocalfileinfo.c:2670
msgid "SELinux context must be non-NULL"
msgstr "SELinux 情境必須為非-NULL"
-#: gio/glocalfileinfo.c:2720
-msgid "SELinux is not enabled on this system"
-msgstr "SELinux 在這個系統上並未啟用"
-
-#: gio/glocalfileinfo.c:2730
+#: gio/glocalfileinfo.c:2685
#, c-format
msgid "Error setting SELinux context: %s"
msgstr "設定 SELinux 情境時發生錯誤:%s"
-#: gio/glocalfileinfo.c:2823
+#: gio/glocalfileinfo.c:2692
+msgid "SELinux is not enabled on this system"
+msgstr "SELinux 在這個系統上並未啟用"
+
+#: gio/glocalfileinfo.c:2784
#, c-format
msgid "Setting attribute %s not supported"
msgstr "不支援設定特性 %s"
-#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801
+#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:795
#, c-format
msgid "Error reading from file: %s"
msgstr "從檔案讀取時發生錯誤:%s"
-#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353
-#: gio/glocalfileoutputstream.c:447
-#, c-format
-msgid "Error closing file: %s"
-msgstr "關閉檔案時發生錯誤:%s"
-
-#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563
-#: gio/glocalfileoutputstream.c:1157
+#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211
+#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333
+#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:1117
#, c-format
msgid "Error seeking in file: %s"
msgstr "在檔案中搜尋時發生錯誤:%s"
-#: gio/glocalfilemonitor.c:866
+#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:347
+#: gio/glocalfileoutputstream.c:441
+#, c-format
+msgid "Error closing file: %s"
+msgstr "關閉檔案時發生錯誤:%s"
+
+#: gio/glocalfilemonitor.c:865
msgid "Unable to find default local file monitor type"
msgstr "無法找到預設的本地端檔案監視器類型"
-#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298
-#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822
+#: gio/glocalfileoutputstream.c:214 gio/glocalfileoutputstream.c:292
+#: gio/glocalfileoutputstream.c:328 gio/glocalfileoutputstream.c:816
#, c-format
msgid "Error writing to file: %s"
msgstr "寫入至檔案時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:380
+#: gio/glocalfileoutputstream.c:374
#, c-format
msgid "Error removing old backup link: %s"
msgstr "移除舊備份連結時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407
+#: gio/glocalfileoutputstream.c:388 gio/glocalfileoutputstream.c:401
#, c-format
msgid "Error creating backup copy: %s"
msgstr "建立備份複本時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:425
+#: gio/glocalfileoutputstream.c:419
#, c-format
msgid "Error renaming temporary file: %s"
msgstr "重新命名暫存檔案時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1208
+#: gio/glocalfileoutputstream.c:603 gio/glocalfileoutputstream.c:1168
#, c-format
msgid "Error truncating file: %s"
msgstr "截短檔案時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907
-#: gio/glocalfileoutputstream.c:1189 gio/gsubprocess.c:226
+#: gio/glocalfileoutputstream.c:656 gio/glocalfileoutputstream.c:894
+#: gio/glocalfileoutputstream.c:1149 gio/gsubprocess.c:380
#, c-format
msgid "Error opening file “%s”: %s"
msgstr "開啟檔案「%s」時發生錯誤:%s"
-#: gio/glocalfileoutputstream.c:957
+#: gio/glocalfileoutputstream.c:928
msgid "Target file is a directory"
msgstr "目標檔案是一個目錄"
-#: gio/glocalfileoutputstream.c:971
+#: gio/glocalfileoutputstream.c:933
msgid "Target file is not a regular file"
msgstr "目標檔案不是正規的檔案"
-#: gio/glocalfileoutputstream.c:984
+#: gio/glocalfileoutputstream.c:945
msgid "The file was externally modified"
msgstr "該檔案已被外部程式修改過"
-#: gio/glocalfileoutputstream.c:1173
+#: gio/glocalfileoutputstream.c:1133
#, c-format
msgid "Error removing old file: %s"
msgstr "移除舊檔案時發生錯誤:%s"
@@ -3361,15 +3274,15 @@ msgstr "%s 未實作"
msgid "Invalid domain"
msgstr "網域無效"
-#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983
-#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253
-#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599
+#: gio/gresource.c:672 gio/gresource.c:931 gio/gresource.c:970
+#: gio/gresource.c:1094 gio/gresource.c:1166 gio/gresource.c:1239
+#: gio/gresource.c:1320 gio/gresourcefile.c:476 gio/gresourcefile.c:599
#: gio/gresourcefile.c:736
#, c-format
msgid "The resource at “%s” does not exist"
msgstr "「%s」的資源不存在"
-#: gio/gresource.c:848
+#: gio/gresource.c:837
#, c-format
msgid "The resource at “%s” failed to decompress"
msgstr "「%s」的資源無法解壓縮"
@@ -3743,7 +3656,7 @@ msgstr "無效的 socket,初始化失敗原因為:%s"
msgid "Socket is already closed"
msgstr "Socket 已經關閉"
-#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478
+#: gio/gsocket.c:443 gio/gsocket.c:3180 gio/gsocket.c:4403 gio/gsocket.c:4461
msgid "Socket I/O timed out"
msgstr "Socket I/O 逾時"
@@ -3752,181 +3665,176 @@ msgstr "Socket I/O 逾時"
msgid "creating GSocket from fd: %s"
msgstr "正在從 fd 建立 GSocket:%s"
-#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678
+#: gio/gsocket.c:607 gio/gsocket.c:661 gio/gsocket.c:668
#, c-format
msgid "Unable to create socket: %s"
msgstr "無法建立 socket:%s"
-#: gio/gsocket.c:671
+#: gio/gsocket.c:661
msgid "Unknown family was specified"
msgstr "指定了不明的字族"
-#: gio/gsocket.c:678
+#: gio/gsocket.c:668
msgid "Unknown protocol was specified"
msgstr "指定了不明的通訊協定"
-#: gio/gsocket.c:1169
+#: gio/gsocket.c:1159
#, c-format
msgid "Cannot use datagram operations on a non-datagram socket."
msgstr "不能在非資料電報 socket 上使用資料電報操作。"
-#: gio/gsocket.c:1186
+#: gio/gsocket.c:1176
#, c-format
msgid "Cannot use datagram operations on a socket with a timeout set."
msgstr "不能在有逾時設定 socket 上使用資料電報操作。"
-#: gio/gsocket.c:1993
+#: gio/gsocket.c:1983
#, c-format
msgid "could not get local address: %s"
msgstr "無法取得本地端位址:%s"
-#: gio/gsocket.c:2039
+#: gio/gsocket.c:2029
#, c-format
msgid "could not get remote address: %s"
msgstr "無法取得遠端位址:%s"
-#: gio/gsocket.c:2105
+#: gio/gsocket.c:2095
#, c-format
msgid "could not listen: %s"
msgstr "無法聽取:%s"
-#: gio/gsocket.c:2209
+#: gio/gsocket.c:2199
#, c-format
msgid "Error binding to address %s: %s"
msgstr "綁定至 %s 位址時發生錯誤:%s"
-#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557
-#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696
+#: gio/gsocket.c:2375 gio/gsocket.c:2412 gio/gsocket.c:2522 gio/gsocket.c:2547
+#: gio/gsocket.c:2610 gio/gsocket.c:2668 gio/gsocket.c:2686
#, c-format
msgid "Error joining multicast group: %s"
msgstr "加入多點廣播群組時發生錯誤:%s"
-#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558
-#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697
+#: gio/gsocket.c:2376 gio/gsocket.c:2413 gio/gsocket.c:2523 gio/gsocket.c:2548
+#: gio/gsocket.c:2611 gio/gsocket.c:2669 gio/gsocket.c:2687
#, c-format
msgid "Error leaving multicast group: %s"
msgstr "離開多點廣播群組時發生錯誤:%s"
-#: gio/gsocket.c:2387
+#: gio/gsocket.c:2377
msgid "No support for source-specific multicast"
msgstr "不支援指定來源的多點廣播"
-#: gio/gsocket.c:2534
+#: gio/gsocket.c:2524
msgid "Unsupported socket family"
msgstr "不支援的 socket 家族"
-#: gio/gsocket.c:2559
+#: gio/gsocket.c:2549
msgid "source-specific not an IPv4 address"
msgstr "指定來源不是 IPv4 位址"
-#: gio/gsocket.c:2583
+#: gio/gsocket.c:2573
#, c-format
msgid "Interface name too long"
msgstr "介面名稱過長"
-#: gio/gsocket.c:2596 gio/gsocket.c:2646
+#: gio/gsocket.c:2586 gio/gsocket.c:2636
#, c-format
msgid "Interface not found: %s"
msgstr "找不到介面:%s"
-#: gio/gsocket.c:2622
+#: gio/gsocket.c:2612
msgid "No support for IPv4 source-specific multicast"
msgstr "不支援 IPv4 指定來源的多點廣播"
-#: gio/gsocket.c:2680
+#: gio/gsocket.c:2670
msgid "No support for IPv6 source-specific multicast"
msgstr "不支援 IPv6 指定來源的多點廣播"
-#: gio/gsocket.c:2889
+#: gio/gsocket.c:2879
#, c-format
msgid "Error accepting connection: %s"
msgstr "接受連線時發生錯誤:%s"
-#: gio/gsocket.c:3015
+#: gio/gsocket.c:3005
msgid "Connection in progress"
msgstr "連線進行中"
-#: gio/gsocket.c:3066
+#: gio/gsocket.c:3056
msgid "Unable to get pending error: "
msgstr "無法取得未處理的錯誤:"
-#: gio/gsocket.c:3255
+#: gio/gsocket.c:3245
#, c-format
msgid "Error receiving data: %s"
msgstr "接收資料時發生錯誤:%s"
-#: gio/gsocket.c:3452
+#: gio/gsocket.c:3442
#, c-format
msgid "Error sending data: %s"
msgstr "傳送資料時發生錯誤:%s"
-#: gio/gsocket.c:3639
+#: gio/gsocket.c:3629
#, c-format
msgid "Unable to shutdown socket: %s"
msgstr "無法關閉 socket:%s"
-#: gio/gsocket.c:3720
+#: gio/gsocket.c:3710
#, c-format
msgid "Error closing socket: %s"
msgstr "關閉 socket 時發生錯誤:%s"
-#: gio/gsocket.c:4413
+#: gio/gsocket.c:4396
#, c-format
msgid "Waiting for socket condition: %s"
msgstr "等候 socket 情況:%s"
-#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833
-#, c-format
-msgid "Unable to send message: %s"
-msgstr "無法傳送訊息:%s"
-
-#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834
-msgid "Message vectors too large"
-msgstr "訊息係數過大"
-
-#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084
-#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304
+#: gio/gsocket.c:4774 gio/gsocket.c:4776 gio/gsocket.c:4923 gio/gsocket.c:5008
+#: gio/gsocket.c:5186 gio/gsocket.c:5226 gio/gsocket.c:5228
#, c-format
msgid "Error sending message: %s"
msgstr "傳送訊息時發生錯誤:%s"
-#: gio/gsocket.c:5026
+#: gio/gsocket.c:4950
msgid "GSocketControlMessage not supported on Windows"
msgstr "視窗不支援 GSocketControlMessage"
-#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797
+#: gio/gsocket.c:5419 gio/gsocket.c:5492 gio/gsocket.c:5718
#, c-format
msgid "Error receiving message: %s"
msgstr "取回郵件發生錯誤:%s"
-#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127
+#: gio/gsocket.c:5990 gio/gsocket.c:6038
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "無法讀取 socket 機密:%s"
-#: gio/gsocket.c:6136
+#: gio/gsocket.c:6047
msgid "g_socket_get_credentials not implemented for this OS"
msgstr "g_socket_get_credentials 沒有在這個 OS 上實作"
-#: gio/gsocketclient.c:191
+#: gio/gsocketclient.c:182
#, c-format
msgid "Could not connect to proxy server %s: "
msgstr "無法連線到代理伺服器 %s:"
-#: gio/gsocketclient.c:205
+#: gio/gsocketclient.c:196
#, c-format
msgid "Could not connect to %s: "
msgstr "無法連接到 %s:"
-#: gio/gsocketclient.c:207
+#: gio/gsocketclient.c:198
msgid "Could not connect: "
msgstr "無法連接:"
-#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749
+#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866
+msgid "Unknown error on connect"
+msgstr "連線時有不明的錯誤"
+
+#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668
msgid "Proxying over a non-TCP connection is not supported."
msgstr "不支援嘗試透過非-TCP 連線使用代理伺服器。"
-#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778
+#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698
#, c-format
msgid "Proxy protocol “%s” is not supported."
msgstr "指定的通訊協定「%s」不被支援。"
@@ -4055,30 +3963,26 @@ msgstr "暫時無法解析「%s」"
msgid "Error resolving “%s”"
msgstr "解析「%s」時發生錯誤"
-#: gio/gtlscertificate.c:298
+#: gio/gtlscertificate.c:243
msgid "No PEM-encoded private key found"
msgstr "找不到 PEM 編碼的私鑰"
-#: gio/gtlscertificate.c:308
+#: gio/gtlscertificate.c:253
msgid "Cannot decrypt PEM-encoded private key"
msgstr "不能解鎖 PEM 編碼的私鑰"
-#: gio/gtlscertificate.c:319
+#: gio/gtlscertificate.c:264
msgid "Could not parse PEM-encoded private key"
msgstr "無法解析 PEM 編碼的私鑰"
-#: gio/gtlscertificate.c:346
+#: gio/gtlscertificate.c:291
msgid "No PEM-encoded certificate found"
msgstr "找到非 PEM 編碼的憑證"
-#: gio/gtlscertificate.c:355
+#: gio/gtlscertificate.c:300
msgid "Could not parse PEM-encoded certificate"
msgstr "無法解析 PEM 編碼的憑證"
-#: gio/gtlscertificate.c:710
-msgid "This GTlsBackend does not support creating PKCS #11 certificates"
-msgstr "這個 GTlsBackend 不支援建立does PKCS #11 憑證"
-
#: gio/gtlspassword.c:111
msgid ""
"This is the last chance to enter the password correctly before your access "
@@ -4147,24 +4051,24 @@ msgstr "不是預期的控制訊息,卻收到 %d"
msgid "Error while disabling SO_PASSCRED: %s"
msgstr "停用 SO_PASSCRED 時發生錯誤:%s"
-#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378
+#: gio/gunixinputstream.c:362 gio/gunixinputstream.c:383
#, c-format
msgid "Error reading from file descriptor: %s"
msgstr "讀取檔案描述狀態時發生錯誤:%s"
-#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520
+#: gio/gunixinputstream.c:416 gio/gunixoutputstream.c:525
#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204
#, c-format
msgid "Error closing file descriptor: %s"
msgstr "關閉檔案描述狀態時發生錯誤:%s"
-#: gio/gunixmounts.c:2780 gio/gunixmounts.c:2833
+#: gio/gunixmounts.c:2755 gio/gunixmounts.c:2808
msgid "Filesystem root"
msgstr "根檔案系統"
-#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377
-#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484
-#: gio/gunixoutputstream.c:630
+#: gio/gunixoutputstream.c:362 gio/gunixoutputstream.c:382
+#: gio/gunixoutputstream.c:469 gio/gunixoutputstream.c:489
+#: gio/gunixoutputstream.c:635
#, c-format
msgid "Error writing to file descriptor: %s"
msgstr "寫入檔案描述狀態時發生錯誤:%s"
@@ -4368,25 +4272,25 @@ msgid "The pathname “%s” is not an absolute path"
msgstr "路徑名稱「%s」不是絕對路徑"
#. Translators: this is the preferred format for expressing the date and the time
-#: glib/gdatetime.c:226
+#: glib/gdatetime.c:220
msgctxt "GDateTime"
msgid "%a %b %e %H:%M:%S %Y"
msgstr "%Y年%m月%d日 (%A) %H時%M分%S秒"
#. Translators: this is the preferred format for expressing the date
-#: glib/gdatetime.c:229
+#: glib/gdatetime.c:223
msgctxt "GDateTime"
msgid "%m/%d/%y"
msgstr "%y/%m/%d"
#. Translators: this is the preferred format for expressing the time
-#: glib/gdatetime.c:232
+#: glib/gdatetime.c:226
msgctxt "GDateTime"
msgid "%H:%M:%S"
msgstr "%H:%M:%S"
#. Translators: this is the preferred format for expressing 12 hour time
-#: glib/gdatetime.c:235
+#: glib/gdatetime.c:229
msgctxt "GDateTime"
msgid "%I:%M:%S %p"
msgstr "%p %I時%M分%S秒"
@@ -4407,62 +4311,62 @@ msgstr "%p %I時%M分%S秒"
#. * non-European) there is no difference between the standalone and
#. * complete date form.
#.
-#: glib/gdatetime.c:274
+#: glib/gdatetime.c:268
msgctxt "full month name"
msgid "January"
msgstr "一月"
-#: glib/gdatetime.c:276
+#: glib/gdatetime.c:270
msgctxt "full month name"
msgid "February"
msgstr "二月"
-#: glib/gdatetime.c:278
+#: glib/gdatetime.c:272
msgctxt "full month name"
msgid "March"
msgstr "三月"
-#: glib/gdatetime.c:280
+#: glib/gdatetime.c:274
msgctxt "full month name"
msgid "April"
msgstr "四月"
-#: glib/gdatetime.c:282
+#: glib/gdatetime.c:276
msgctxt "full month name"
msgid "May"
msgstr "五月"
-#: glib/gdatetime.c:284
+#: glib/gdatetime.c:278
msgctxt "full month name"
msgid "June"
msgstr "六月"
-#: glib/gdatetime.c:286
+#: glib/gdatetime.c:280
msgctxt "full month name"
msgid "July"
msgstr "七月"
-#: glib/gdatetime.c:288
+#: glib/gdatetime.c:282
msgctxt "full month name"
msgid "August"
msgstr "八月"
-#: glib/gdatetime.c:290
+#: glib/gdatetime.c:284
msgctxt "full month name"
msgid "September"
msgstr "九月"
-#: glib/gdatetime.c:292
+#: glib/gdatetime.c:286
msgctxt "full month name"
msgid "October"
msgstr "十月"
-#: glib/gdatetime.c:294
+#: glib/gdatetime.c:288
msgctxt "full month name"
msgid "November"
msgstr "十一月"
-#: glib/gdatetime.c:296
+#: glib/gdatetime.c:290
msgctxt "full month name"
msgid "December"
msgstr "十二月"
@@ -4484,132 +4388,132 @@ msgstr "十二月"
#. * other platform. Here are abbreviated month names in a form
#. * appropriate when they are used standalone.
#.
-#: glib/gdatetime.c:328
+#: glib/gdatetime.c:322
msgctxt "abbreviated month name"
msgid "Jan"
msgstr "一月"
-#: glib/gdatetime.c:330
+#: glib/gdatetime.c:324
msgctxt "abbreviated month name"
msgid "Feb"
msgstr "二月"
-#: glib/gdatetime.c:332
+#: glib/gdatetime.c:326
msgctxt "abbreviated month name"
msgid "Mar"
msgstr "三月"
-#: glib/gdatetime.c:334
+#: glib/gdatetime.c:328
msgctxt "abbreviated month name"
msgid "Apr"
msgstr "四月"
-#: glib/gdatetime.c:336
+#: glib/gdatetime.c:330
msgctxt "abbreviated month name"
msgid "May"
msgstr "五月"
-#: glib/gdatetime.c:338
+#: glib/gdatetime.c:332
msgctxt "abbreviated month name"
msgid "Jun"
msgstr "六月"
-#: glib/gdatetime.c:340
+#: glib/gdatetime.c:334
msgctxt "abbreviated month name"
msgid "Jul"
msgstr "七月"
-#: glib/gdatetime.c:342
+#: glib/gdatetime.c:336
msgctxt "abbreviated month name"
msgid "Aug"
msgstr "八月"
-#: glib/gdatetime.c:344
+#: glib/gdatetime.c:338
msgctxt "abbreviated month name"
msgid "Sep"
msgstr "九月"
-#: glib/gdatetime.c:346
+#: glib/gdatetime.c:340
msgctxt "abbreviated month name"
msgid "Oct"
msgstr "十月"
-#: glib/gdatetime.c:348
+#: glib/gdatetime.c:342
msgctxt "abbreviated month name"
msgid "Nov"
msgstr "十一月"
-#: glib/gdatetime.c:350
+#: glib/gdatetime.c:344
msgctxt "abbreviated month name"
msgid "Dec"
msgstr "十二月"
-#: glib/gdatetime.c:365
+#: glib/gdatetime.c:359
msgctxt "full weekday name"
msgid "Monday"
msgstr "星期一"
-#: glib/gdatetime.c:367
+#: glib/gdatetime.c:361
msgctxt "full weekday name"
msgid "Tuesday"
msgstr "星期二"
-#: glib/gdatetime.c:369
+#: glib/gdatetime.c:363
msgctxt "full weekday name"
msgid "Wednesday"
msgstr "星期三"
-#: glib/gdatetime.c:371
+#: glib/gdatetime.c:365
msgctxt "full weekday name"
msgid "Thursday"
msgstr "星期四"
-#: glib/gdatetime.c:373
+#: glib/gdatetime.c:367
msgctxt "full weekday name"
msgid "Friday"
msgstr "星期五"
-#: glib/gdatetime.c:375
+#: glib/gdatetime.c:369
msgctxt "full weekday name"
msgid "Saturday"
msgstr "星期六"
-#: glib/gdatetime.c:377
+#: glib/gdatetime.c:371
msgctxt "full weekday name"
msgid "Sunday"
msgstr "星期日"
-#: glib/gdatetime.c:392
+#: glib/gdatetime.c:386
msgctxt "abbreviated weekday name"
msgid "Mon"
msgstr "週一"
-#: glib/gdatetime.c:394
+#: glib/gdatetime.c:388
msgctxt "abbreviated weekday name"
msgid "Tue"
msgstr "週二"
-#: glib/gdatetime.c:396
+#: glib/gdatetime.c:390
msgctxt "abbreviated weekday name"
msgid "Wed"
msgstr "週三"
-#: glib/gdatetime.c:398
+#: glib/gdatetime.c:392
msgctxt "abbreviated weekday name"
msgid "Thu"
msgstr "週四"
-#: glib/gdatetime.c:400
+#: glib/gdatetime.c:394
msgctxt "abbreviated weekday name"
msgid "Fri"
msgstr "週五"
-#: glib/gdatetime.c:402
+#: glib/gdatetime.c:396
msgctxt "abbreviated weekday name"
msgid "Sat"
msgstr "週六"
-#: glib/gdatetime.c:404
+#: glib/gdatetime.c:398
msgctxt "abbreviated weekday name"
msgid "Sun"
msgstr "週日"
@@ -4631,62 +4535,62 @@ msgstr "週日"
#. * (western European, non-European) there is no difference between the
#. * standalone and complete date form.
#.
-#: glib/gdatetime.c:468
+#: glib/gdatetime.c:462
msgctxt "full month name with day"
msgid "January"
msgstr "一月"
-#: glib/gdatetime.c:470
+#: glib/gdatetime.c:464
msgctxt "full month name with day"
msgid "February"
msgstr "二月"
-#: glib/gdatetime.c:472
+#: glib/gdatetime.c:466
msgctxt "full month name with day"
msgid "March"
msgstr "三月"
-#: glib/gdatetime.c:474
+#: glib/gdatetime.c:468
msgctxt "full month name with day"
msgid "April"
msgstr "四月"
-#: glib/gdatetime.c:476
+#: glib/gdatetime.c:470
msgctxt "full month name with day"
msgid "May"
msgstr "五月"
-#: glib/gdatetime.c:478
+#: glib/gdatetime.c:472
msgctxt "full month name with day"
msgid "June"
msgstr "六月"
-#: glib/gdatetime.c:480
+#: glib/gdatetime.c:474
msgctxt "full month name with day"
msgid "July"
msgstr "七月"
-#: glib/gdatetime.c:482
+#: glib/gdatetime.c:476
msgctxt "full month name with day"
msgid "August"
msgstr "八月"
-#: glib/gdatetime.c:484
+#: glib/gdatetime.c:478
msgctxt "full month name with day"
msgid "September"
msgstr "九月"
-#: glib/gdatetime.c:486
+#: glib/gdatetime.c:480
msgctxt "full month name with day"
msgid "October"
msgstr "十月"
-#: glib/gdatetime.c:488
+#: glib/gdatetime.c:482
msgctxt "full month name with day"
msgid "November"
msgstr "十一月"
-#: glib/gdatetime.c:490
+#: glib/gdatetime.c:484
msgctxt "full month name with day"
msgid "December"
msgstr "十二月"
@@ -4708,74 +4612,74 @@ msgstr "十二月"
#. * month names almost ready to copy and paste here. In other systems
#. * due to a bug the result is incorrect in some languages.
#.
-#: glib/gdatetime.c:555
+#: glib/gdatetime.c:549
msgctxt "abbreviated month name with day"
msgid "Jan"
msgstr "一月"
-#: glib/gdatetime.c:557
+#: glib/gdatetime.c:551
msgctxt "abbreviated month name with day"
msgid "Feb"
msgstr "二月"
-#: glib/gdatetime.c:559
+#: glib/gdatetime.c:553
msgctxt "abbreviated month name with day"
msgid "Mar"
msgstr "三月"
-#: glib/gdatetime.c:561
+#: glib/gdatetime.c:555
msgctxt "abbreviated month name with day"
msgid "Apr"
msgstr "四月"
-#: glib/gdatetime.c:563
+#: glib/gdatetime.c:557
msgctxt "abbreviated month name with day"
msgid "May"
msgstr "五月"
-#: glib/gdatetime.c:565
+#: glib/gdatetime.c:559
msgctxt "abbreviated month name with day"
msgid "Jun"
msgstr "六月"
-#: glib/gdatetime.c:567
+#: glib/gdatetime.c:561
msgctxt "abbreviated month name with day"
msgid "Jul"
msgstr "七月"
-#: glib/gdatetime.c:569
+#: glib/gdatetime.c:563
msgctxt "abbreviated month name with day"
msgid "Aug"
msgstr "八月"
-#: glib/gdatetime.c:571
+#: glib/gdatetime.c:565
msgctxt "abbreviated month name with day"
msgid "Sep"
msgstr "九月"
-#: glib/gdatetime.c:573
+#: glib/gdatetime.c:567
msgctxt "abbreviated month name with day"
msgid "Oct"
msgstr "十月"
-#: glib/gdatetime.c:575
+#: glib/gdatetime.c:569
msgctxt "abbreviated month name with day"
msgid "Nov"
msgstr "十一月"
-#: glib/gdatetime.c:577
+#: glib/gdatetime.c:571
msgctxt "abbreviated month name with day"
msgid "Dec"
msgstr "十二月"
#. Translators: 'before midday' indicator
-#: glib/gdatetime.c:594
+#: glib/gdatetime.c:588
msgctxt "GDateTime"
msgid "AM"
msgstr "上午"
#. Translators: 'after midday' indicator
-#: glib/gdatetime.c:597
+#: glib/gdatetime.c:591
msgctxt "GDateTime"
msgid "PM"
msgstr "下午"
@@ -4806,176 +4710,176 @@ msgstr "檔案「%s」太過巨大"
msgid "Failed to read from file “%s”: %s"
msgstr "讀取檔案「%s」失敗:%s"
-#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1476
+#: glib/gfileutils.c:902 glib/gfileutils.c:974 glib/gfileutils.c:1466
#, c-format
msgid "Failed to open file “%s”: %s"
msgstr "開啟檔案「%s」失敗:%s"
-#: glib/gfileutils.c:917
+#: glib/gfileutils.c:914
#, c-format
msgid "Failed to get attributes of file “%s”: fstat() failed: %s"
msgstr "獲取檔案「%s」的特性失敗:fstat() 失敗:%s"
-#: glib/gfileutils.c:948
+#: glib/gfileutils.c:944
#, c-format
msgid "Failed to open file “%s”: fdopen() failed: %s"
msgstr "開啟檔案「%s」失敗:fdopen() 失敗:%s"
-#: glib/gfileutils.c:1049
+#: glib/gfileutils.c:1044
#, c-format
msgid "Failed to rename file “%s” to “%s”: g_rename() failed: %s"
msgstr "檔案名稱由「%s」改為「%s」失敗:g_rename() 失敗:%s"
-#: glib/gfileutils.c:1175
+#: glib/gfileutils.c:1169
#, c-format
msgid "Failed to write file “%s”: write() failed: %s"
msgstr "無法寫入檔案「%s」:write() 失敗:%s"
-#: glib/gfileutils.c:1196
+#: glib/gfileutils.c:1189
#, c-format
msgid "Failed to write file “%s”: fsync() failed: %s"
msgstr "無法寫入檔案「%s」:fsync() 失敗:%s"
-#: glib/gfileutils.c:1365 glib/gfileutils.c:1780
+#: glib/gfileutils.c:1357 glib/gfileutils.c:1769
#, c-format
msgid "Failed to create file “%s”: %s"
msgstr "建立檔案「%s」失敗:%s"
-#: glib/gfileutils.c:1410
+#: glib/gfileutils.c:1401
#, c-format
msgid "Existing file “%s” could not be removed: g_unlink() failed: %s"
msgstr "現存檔案「%s」無法移除:g_unlink() 失敗:%s"
-#: glib/gfileutils.c:1745
+#: glib/gfileutils.c:1735
#, c-format
msgid "Template “%s” invalid, should not contain a “%s”"
msgstr "範本「%s」無效,不應含有「%s」"
# (Abel) this is file template for mktemp/mkstemp
-#: glib/gfileutils.c:1758
+#: glib/gfileutils.c:1748
#, c-format
msgid "Template “%s” doesn’t contain XXXXXX"
msgstr "範本「%s」沒有包含 XXXXXX"
-#: glib/gfileutils.c:2318 glib/gfileutils.c:2347
+#: glib/gfileutils.c:2306 glib/gfileutils.c:2334
#, c-format
msgid "Failed to read the symbolic link “%s”: %s"
msgstr "讀取符號連結「%s」失敗:%s"
-#: glib/giochannel.c:1405
+#: glib/giochannel.c:1396
#, c-format
msgid "Could not open converter from “%s” to “%s”: %s"
msgstr "無法開啟將「%s」轉換至「%s」的轉換器:%s"
-#: glib/giochannel.c:1758
+#: glib/giochannel.c:1749
msgid "Can’t do a raw read in g_io_channel_read_line_string"
msgstr "在 g_io_channel_read_line_string 中無法讀取原始資料"
-#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150
+#: glib/giochannel.c:1796 glib/giochannel.c:2054 glib/giochannel.c:2141
msgid "Leftover unconverted data in read buffer"
msgstr "用來讀取資料的緩衝區中仍有未轉換的資料"
-#: glib/giochannel.c:1886 glib/giochannel.c:1963
+#: glib/giochannel.c:1877 glib/giochannel.c:1954
msgid "Channel terminates in a partial character"
msgstr "在字元未完整之前,輸入管道已經結束"
-#: glib/giochannel.c:1949
+#: glib/giochannel.c:1940
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "在 g_io_channel_read_to_end 中無法讀取原始資料"
-#: glib/gkeyfile.c:790
+#: glib/gkeyfile.c:789
msgid "Valid key file could not be found in search dirs"
msgstr "在資料目錄中找不到有效的鍵檔案"
-#: glib/gkeyfile.c:827
+#: glib/gkeyfile.c:826
msgid "Not a regular file"
msgstr "不是正規的檔案"
-#: glib/gkeyfile.c:1282
+#: glib/gkeyfile.c:1275
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
msgstr "鍵檔案中「%s」行並非鍵值配對、群組或註解"
-#: glib/gkeyfile.c:1339
+#: glib/gkeyfile.c:1332
#, c-format
msgid "Invalid group name: %s"
msgstr "無效的群組名稱:%s"
-#: glib/gkeyfile.c:1361
+#: glib/gkeyfile.c:1354
msgid "Key file does not start with a group"
msgstr "鍵檔案並非以群組開頭"
-#: glib/gkeyfile.c:1387
+#: glib/gkeyfile.c:1380
#, c-format
msgid "Invalid key name: %s"
msgstr "無效的鍵名稱:%s"
-#: glib/gkeyfile.c:1414
+#: glib/gkeyfile.c:1407
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "鍵檔案包含不支援的編碼「%s」"
-#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289
-#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615
-#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063
+#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276
+#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602
+#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044
#, c-format
msgid "Key file does not have group “%s”"
msgstr "鍵檔案沒有群組「%s」"
-#: glib/gkeyfile.c:1791
+#: glib/gkeyfile.c:1778
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "鍵檔案的「%2$s」群組中沒有「%1$s」鍵"
-#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069
+#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "鍵檔案包含的「%s」鍵(值為「%s」)並非 UTF-8"
-#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531
+#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
msgstr "鍵檔案包含的「%s」鍵的值無法解譯。"
-#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118
+#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
"interpreted."
msgstr "鍵檔案包含的「%2$s」群組中「%1$s」鍵的值無法解譯。"
-#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904
+#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "「%2$s」群組中的「%1$s」鍵包含「%3$s」值,但預期為「%4$s」"
-#: glib/gkeyfile.c:4306
+#: glib/gkeyfile.c:4284
msgid "Key file contains escape character at end of line"
msgstr "鍵檔案在行尾包含跳出字元"
-#: glib/gkeyfile.c:4328
+#: glib/gkeyfile.c:4306
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "鍵檔案含有不正確的「跳出字元」「%s」"
-#: glib/gkeyfile.c:4472
+#: glib/gkeyfile.c:4450
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "「%s」值不能被解譯為數字。"
-#: glib/gkeyfile.c:4486
+#: glib/gkeyfile.c:4464
#, c-format
msgid "Integer value “%s” out of range"
msgstr "整數值「%s」超出範圍"
-#: glib/gkeyfile.c:4519
+#: glib/gkeyfile.c:4497
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "「%s」值不能被解譯為浮點數。"
-#: glib/gkeyfile.c:4558
+#: glib/gkeyfile.c:4536
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "「%s」值不能被解譯為布林值。"
@@ -5636,82 +5540,82 @@ msgstr "字串完結前仍沒有對應於 %c 的引號 (字串為「%s」)"
msgid "Text was empty (or contained only whitespace)"
msgstr "文字是空白的(或只含有空白字元)"
-#: glib/gspawn.c:318
+#: glib/gspawn.c:323
#, c-format
msgid "Failed to read data from child process (%s)"
msgstr "無法從副進程讀取資料 (%s)"
-#: glib/gspawn.c:465
+#: glib/gspawn.c:468
#, c-format
msgid "Unexpected error in reading data from a child process (%s)"
msgstr "從子程序 (%s) 讀取資料時發生未預期的錯誤"
-#: glib/gspawn.c:550
+#: glib/gspawn.c:553
#, c-format
msgid "Unexpected error in waitpid() (%s)"
msgstr "waitpid() 發生未預期的錯誤 (%s)"
-#: glib/gspawn.c:1154 glib/gspawn-win32.c:1383
+#: glib/gspawn.c:1061 glib/gspawn-win32.c:1329
#, c-format
msgid "Child process exited with code %ld"
msgstr "子程序以代碼 %ld 結束"
-#: glib/gspawn.c:1162
+#: glib/gspawn.c:1069
#, c-format
msgid "Child process killed by signal %ld"
msgstr "子程序被信號 %ld 中止"
-#: glib/gspawn.c:1169
+#: glib/gspawn.c:1076
#, c-format
msgid "Child process stopped by signal %ld"
msgstr "子程序被信號 %ld 停止"
-#: glib/gspawn.c:1176
+#: glib/gspawn.c:1083
#, c-format
msgid "Child process exited abnormally"
msgstr "子程序異常結束"
-#: glib/gspawn.c:1767 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
+#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358
#, c-format
msgid "Failed to read from child pipe (%s)"
msgstr "無法從管道讀取資料 (%s)"
-#: glib/gspawn.c:2069
+#: glib/gspawn.c:1788
#, c-format
msgid "Failed to spawn child process “%s” (%s)"
msgstr "無法產生副程序「%s」(%s)"
-#: glib/gspawn.c:2186
+#: glib/gspawn.c:1871
#, c-format
msgid "Failed to fork (%s)"
msgstr "無法衍生進程 (%s)"
-#: glib/gspawn.c:2346 glib/gspawn-win32.c:381
+#: glib/gspawn.c:2026 glib/gspawn-win32.c:381
#, c-format
msgid "Failed to change to directory “%s” (%s)"
msgstr "無法進入目錄「%s」(%s)"
-#: glib/gspawn.c:2356
+#: glib/gspawn.c:2036
#, c-format
msgid "Failed to execute child process “%s” (%s)"
msgstr "無法執行副程序「%s」(%s)"
-#: glib/gspawn.c:2366
+#: glib/gspawn.c:2046
#, c-format
msgid "Failed to redirect output or input of child process (%s)"
msgstr "無法將副進程的輸出或輸入重新導向 (%s)"
-#: glib/gspawn.c:2375
+#: glib/gspawn.c:2055
#, c-format
msgid "Failed to fork child process (%s)"
msgstr "無法衍生副進程 (%s)"
-#: glib/gspawn.c:2383
+#: glib/gspawn.c:2063
#, c-format
msgid "Unknown error executing child process “%s”"
msgstr "執行副程序「%s」時發生不明的錯誤"
-#: glib/gspawn.c:2407
+#: glib/gspawn.c:2087
#, c-format
msgid "Failed to read enough data from child pid pipe (%s)"
msgstr "無法從 child pid pipe 讀取足夠的資料 (%s)"
@@ -5735,104 +5639,99 @@ msgstr "無法執行副進程 (%s)"
msgid "Invalid program name: %s"
msgstr "程式名稱無效:%s"
-#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:757
+#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725
#, c-format
msgid "Invalid string in argument vector at %d: %s"
msgstr "第 %d 個引數向量中含無效的字串:%s"
-#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:772
+#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740
#, c-format
msgid "Invalid string in environment: %s"
msgstr "環境變數中的字串無效:%s"
-#: glib/gspawn-win32.c:753
+#: glib/gspawn-win32.c:721
#, c-format
msgid "Invalid working directory: %s"
msgstr "無效的工作目錄:%s"
-#: glib/gspawn-win32.c:815
+#: glib/gspawn-win32.c:783
#, c-format
msgid "Failed to execute helper program (%s)"
msgstr "無法執行協助程式 (%s)"
-#: glib/gspawn-win32.c:1042
+#: glib/gspawn-win32.c:1056
msgid ""
"Unexpected error in g_io_channel_win32_poll() reading data from a child "
"process"
msgstr "當 g_io_channel_win32_poll() 從副進程讀取資料時發生無法預計的錯誤"
-#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440
+#: glib/gstrfuncs.c:3303 glib/gstrfuncs.c:3405
msgid "Empty string is not a number"
msgstr "空字串不是數字"
-#: glib/gstrfuncs.c:3362
+#: glib/gstrfuncs.c:3327
#, c-format
msgid "“%s” is not a signed number"
msgstr "「%s」不是有號數字"
-#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476
+#: glib/gstrfuncs.c:3337 glib/gstrfuncs.c:3441
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "「%s」數字超出範圍 [%s, %s]"
-#: glib/gstrfuncs.c:3466
+#: glib/gstrfuncs.c:3431
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "「%s」不是無號數字"
-#: glib/guri.c:315
+#: glib/guri.c:313
#, no-c-format
msgid "Invalid %-encoding in URI"
msgstr "URI 中有無效的 %-編碼"
-#: glib/guri.c:332
+#: glib/guri.c:330
msgid "Illegal character in URI"
msgstr "URI 中有不合規的字元"
-#: glib/guri.c:366
+#: glib/guri.c:359
msgid "Non-UTF-8 characters in URI"
msgstr "URI 中有非 UTF-8 字元"
-#: glib/guri.c:546
+#: glib/guri.c:533
#, c-format
msgid "Invalid IPv6 address ‘%.*s’ in URI"
msgstr "URI 中有無效的 IPv6 位址「%.*s」"
-#: glib/guri.c:601
+#: glib/guri.c:588
#, c-format
msgid "Illegal encoded IP address ‘%.*s’ in URI"
msgstr "URI 中有不合規的編碼 IP 位址「%.*s」"
-#: glib/guri.c:613
-#, c-format
-msgid "Illegal internationalized hostname ‘%.*s’ in URI"
-msgstr "URI 中有不合規的國際化主機名稱「%.*s」"
-
-#: glib/guri.c:645 glib/guri.c:657
+#: glib/guri.c:620 glib/guri.c:632
#, c-format
msgid "Could not parse port ‘%.*s’ in URI"
msgstr "無法解析 URI 中的「%.*s」連接埠"
-#: glib/guri.c:664
+#: glib/guri.c:639
#, c-format
msgid "Port ‘%.*s’ in URI is out of range"
msgstr "URI 中的「%.*s」連接埠超出範圍"
-#: glib/guri.c:1224 glib/guri.c:1288
+#: glib/guri.c:1119 glib/guri.c:1183
#, c-format
msgid "URI ‘%s’ is not an absolute URI"
msgstr "「%s」URI 不是絕對路徑 URI"
-#: glib/guri.c:1230
+#: glib/guri.c:1125
#, c-format
msgid "URI ‘%s’ has no host component"
msgstr "「%s」URI 沒有主機部分"
-#: glib/guri.c:1435
+#: glib/guri.c:1330
msgid "URI is not absolute, and no base URI was provided"
msgstr "URI 不是絕對路徑,且沒有提供基礎 URI"
-#: glib/guri.c:2209
+#: glib/guri.c:2082
msgid "Missing ‘=’ and parameter value"
msgstr "缺失「=」與參數值"
@@ -5854,170 +5753,170 @@ msgid "Character out of range for UTF-16"
msgstr "字元不在 UTF-16 範圍之內"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2767
+#: glib/gutils.c:2759
#, c-format
msgid "%.1f kB"
msgstr "%.1f kB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2769
+#: glib/gutils.c:2761
#, c-format
msgid "%.1f MB"
msgstr "%.1f MB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2771
+#: glib/gutils.c:2763
#, c-format
msgid "%.1f GB"
msgstr "%.1f GB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2773
+#: glib/gutils.c:2765
#, c-format
msgid "%.1f TB"
msgstr "%.1f TB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2775
+#: glib/gutils.c:2767
#, c-format
msgid "%.1f PB"
msgstr "%.1f PB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2777
+#: glib/gutils.c:2769
#, c-format
msgid "%.1f EB"
msgstr "%.1f EB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2781
+#: glib/gutils.c:2773
#, c-format
msgid "%.1f KiB"
msgstr "%.1f KiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2783
+#: glib/gutils.c:2775
#, c-format
msgid "%.1f MiB"
msgstr "%.1f MiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2785
+#: glib/gutils.c:2777
#, c-format
msgid "%.1f GiB"
msgstr "%.1f GiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2787
+#: glib/gutils.c:2779
#, c-format
msgid "%.1f TiB"
msgstr "%.1f TiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2789
+#: glib/gutils.c:2781
#, c-format
msgid "%.1f PiB"
msgstr "%.1f PiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2791
+#: glib/gutils.c:2783
#, c-format
msgid "%.1f EiB"
msgstr "%.1f EiB"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2795
+#: glib/gutils.c:2787
#, c-format
msgid "%.1f kb"
msgstr "%.1f kb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2797
+#: glib/gutils.c:2789
#, c-format
msgid "%.1f Mb"
msgstr "%.1f Mb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2799
+#: glib/gutils.c:2791
#, c-format
msgid "%.1f Gb"
msgstr "%.1f Gb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2801
+#: glib/gutils.c:2793
#, c-format
msgid "%.1f Tb"
msgstr "%.1f Tb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2803
+#: glib/gutils.c:2795
#, c-format
msgid "%.1f Pb"
msgstr "%.1f Pb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2805
+#: glib/gutils.c:2797
#, c-format
msgid "%.1f Eb"
msgstr "%.1f Eb"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2809
+#: glib/gutils.c:2801
#, c-format
msgid "%.1f Kib"
msgstr "%.1f Kib"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2811
+#: glib/gutils.c:2803
#, c-format
msgid "%.1f Mib"
msgstr "%.1f Mib"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2813
+#: glib/gutils.c:2805
#, c-format
msgid "%.1f Gib"
msgstr "%.1f Gib"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2815
+#: glib/gutils.c:2807
#, c-format
msgid "%.1f Tib"
msgstr "%.1f Tib"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2817
+#: glib/gutils.c:2809
#, c-format
msgid "%.1f Pib"
msgstr "%.1f Pib"
#. Translators: Keep the no-break space between %.1f and the unit symbol
-#: glib/gutils.c:2819
+#: glib/gutils.c:2811
#, c-format
msgid "%.1f Eib"
msgstr "%.1f Eib"
-#: glib/gutils.c:2853 glib/gutils.c:2970
+#: glib/gutils.c:2845 glib/gutils.c:2962
#, c-format
msgid "%u byte"
msgid_plural "%u bytes"
msgstr[0] "%u 位元組"
-#: glib/gutils.c:2857
+#: glib/gutils.c:2849
#, c-format
msgid "%u bit"
msgid_plural "%u bits"
msgstr[0] "%u 位元"
#. Translators: the %s in "%s bytes" will always be replaced by a number.
-#: glib/gutils.c:2924
+#: glib/gutils.c:2916
#, c-format
msgid "%s byte"
msgid_plural "%s bytes"
msgstr[0] "%s 位元組"
#. Translators: the %s in "%s bits" will always be replaced by a number.
-#: glib/gutils.c:2929
+#: glib/gutils.c:2921
#, c-format
msgid "%s bit"
msgid_plural "%s bits"
@@ -6028,42 +5927,36 @@ msgstr[0] "%s 位元"
#. * compatibility. Users will not see this string unless a program is using this deprecated function.
#. * Please translate as literally as possible.
#.
-#: glib/gutils.c:2983
+#: glib/gutils.c:2975
#, c-format
msgid "%.1f KB"
msgstr "%.1f KB"
-#: glib/gutils.c:2988
+#: glib/gutils.c:2980
#, c-format
msgid "%.1f MB"
msgstr "%.1f MB"
-#: glib/gutils.c:2993
+#: glib/gutils.c:2985
#, c-format
msgid "%.1f GB"
msgstr "%.1f GB"
-#: glib/gutils.c:2998
+#: glib/gutils.c:2990
#, c-format
msgid "%.1f TB"
msgstr "%.1f TB"
-#: glib/gutils.c:3003
+#: glib/gutils.c:2995
#, c-format
msgid "%.1f PB"
msgstr "%.1f PB"
-#: glib/gutils.c:3008
+#: glib/gutils.c:3000
#, c-format
msgid "%.1f EB"
msgstr "%.1f EB"
-#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "
-#~ msgstr "無法載入 /var/lib/dbus/machine-id 或 /etc/machine-id:"
-
-#~ msgid "Unknown error on connect"
-#~ msgstr "連線時有不明的錯誤"
-
#~ msgid "Error in address “%s” — the family attribute is malformed"
#~ msgstr "位址「%s」有錯誤 — family 屬性的格式不良"
@@ -6111,6 +6004,9 @@ msgstr "%.1f EB"
#~ msgid "Error: signal must be the fully-qualified name.\n"
#~ msgstr "錯誤:信號必須為完全合規定的名稱。\n"
+#~ msgid "No files given"
+#~ msgstr "尚未指定檔案"
+
#~ msgid "Error getting writable attributes: %s\n"
#~ msgstr "取得可寫入屬性時發生錯誤:%s\n"
diff --git a/subprojects/gtk-doc.wrap b/subprojects/gtk-doc.wrap
index 79ec37220..0490a03a1 100644
--- a/subprojects/gtk-doc.wrap
+++ b/subprojects/gtk-doc.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory=gtk-doc
url=https://gitlab.gnome.org/GNOME/gtk-doc.git
-revision=master
+revision=1.33.2
depth=1
diff --git a/subprojects/libpcre.wrap b/subprojects/libpcre.wrap
new file mode 100644
index 000000000..e27a198ec
--- /dev/null
+++ b/subprojects/libpcre.wrap
@@ -0,0 +1,11 @@
+[wrap-file]
+directory = pcre-8.37
+source_url = https://ftp.pcre.org/pub/pcre/pcre-8.37.tar.bz2
+source_filename = pcre-8.37.tar.bz2
+source_hash = 51679ea8006ce31379fb0860e46dd86665d864b5020fc9cd19e71260eef4789d
+patch_filename = pcre_8.37-2_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/pcre_8.37-2/get_patch
+patch_hash = 6b80f72385e1bf06721e26fbc83aced576e9c0d3182d86a55dd173a04050fe26
+
+[provide]
+libpcre = pcre_dep
diff --git a/tests/dirname-test.c b/tests/dirname-test.c
index 52a4678f1..81c55d56d 100644
--- a/tests/dirname-test.c
+++ b/tests/dirname-test.c
@@ -53,7 +53,7 @@ int
main (int argc,
char *argv[])
{
- gint i;
+ gsize i;
struct {
gchar *filename;
gchar *dirname;
@@ -100,9 +100,8 @@ main (int argc,
{ "a:\\/", "a:\\" },
#endif
};
- guint n_dirname_checks = sizeof (dirname_checks) / sizeof (dirname_checks[0]);
- for (i = 0; i < n_dirname_checks; i++)
+ for (i = 0; i < G_N_ELEMENTS (dirname_checks); i++)
{
gchar *dirname;
diff --git a/tests/gio-test.c b/tests/gio-test.c
index deffa4d09..6c40632b3 100644
--- a/tests/gio-test.c
+++ b/tests/gio-test.c
@@ -130,7 +130,8 @@ recv_message (GIOChannel *channel,
char buf[BUFSIZE];
guint nbytes;
guint nb;
- int i, j, seq;
+ guint j;
+ int i, seq;
GIOError error;
error = read_all (fd, channel, (gchar *) &seq, sizeof (seq), &nb);
@@ -169,7 +170,7 @@ recv_message (GIOChannel *channel,
g_assert (nb == sizeof (nbytes));
g_assert_cmpint (nbytes, <, BUFSIZE);
- g_assert (nbytes >= 0 && nbytes < BUFSIZE);
+ g_assert (nbytes < BUFSIZE);
g_debug ("gio-test: ...from %d: %d bytes", fd, nbytes);
if (nbytes > 0)
{
@@ -186,7 +187,7 @@ recv_message (GIOChannel *channel,
}
for (j = 0; j < nbytes; j++)
- g_assert (buf[j] == ' ' + ((nbytes + j) % 95));
+ g_assert (buf[j] == ' ' + (char) ((nbytes + j) % 95));
g_debug ("gio-test: ...from %d: OK", fd);
}
}
diff --git a/tests/gobject/defaultiface.c b/tests/gobject/defaultiface.c
index eccb79ced..92e45cefb 100644
--- a/tests/gobject/defaultiface.c
+++ b/tests/gobject/defaultiface.c
@@ -122,7 +122,12 @@ test_dynamic_iface_register (GTypeModule *module)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) test_dynamic_iface_default_init,
- (GClassFinalizeFunc) test_dynamic_iface_default_finalize
+ (GClassFinalizeFunc) test_dynamic_iface_default_finalize,
+ NULL,
+ 0,
+ 0,
+ NULL,
+ NULL
};
test_dynamic_iface_type = g_type_module_register_type (module, G_TYPE_INTERFACE,
diff --git a/tests/gobject/performance-threaded.c b/tests/gobject/performance-threaded.c
index c98541d66..af8cc79b0 100644
--- a/tests/gobject/performance-threaded.c
+++ b/tests/gobject/performance-threaded.c
@@ -197,7 +197,7 @@ static const PerformanceTest tests[] = {
};
static gboolean verbose = FALSE;
-static int n_threads = 0;
+static guint n_threads = 0;
static gboolean list = FALSE;
static int test_length = DEFAULT_TEST_TIME;
@@ -210,7 +210,7 @@ static GOptionEntry cmd_entries[] = {
"Time to run each test in seconds", NULL},
{"list", 'l', 0, G_OPTION_ARG_NONE, &list,
"List all available tests and exit", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
static gpointer
@@ -320,7 +320,7 @@ run_test (const PerformanceTest *test)
static const PerformanceTest *
find_test (const char *name)
{
- int i;
+ gsize i;
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
if (strcmp (tests[i].name, name) == 0)
@@ -336,7 +336,7 @@ main (int argc,
const PerformanceTest *test;
GOptionContext *context;
GError *error = NULL;
- int i;
+ gsize i;
context = g_option_context_new ("GObject performance tests");
g_option_context_add_main_entries (context, cmd_entries, NULL);
@@ -357,9 +357,10 @@ main (int argc,
if (argc > 1)
{
- for (i = 1; i < argc; i++)
+ int k;
+ for (k = 1; k < argc; k++)
{
- test = find_test (argv[i]);
+ test = find_test (argv[k]);
if (test)
run_test (test);
}
diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c
index 163be58b4..5208172bd 100644
--- a/tests/gobject/performance.c
+++ b/tests/gobject/performance.c
@@ -37,7 +37,7 @@ static GOptionEntry cmd_entries[] = {
"Print extra information", NULL},
{"seconds", 's', 0, G_OPTION_ARG_INT, &test_length,
"Time to run each test in seconds", NULL},
- {NULL}
+ G_OPTION_ENTRY_NULL
};
typedef struct _PerformanceTest PerformanceTest;
@@ -1015,7 +1015,7 @@ static PerformanceTest tests[] = {
static PerformanceTest *
find_test (const char *name)
{
- int i;
+ gsize i;
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
if (strcmp (tests[i].name, name) == 0)
@@ -1051,8 +1051,9 @@ main (int argc,
}
else
{
- for (i = 0; i < G_N_ELEMENTS (tests); i++)
- run_test (&tests[i]);
+ gsize k;
+ for (k = 0; k < G_N_ELEMENTS (tests); k++)
+ run_test (&tests[k]);
}
return 0;
diff --git a/tests/gobject/references.c b/tests/gobject/references.c
index 8c1266042..36ff35c63 100644
--- a/tests/gobject/references.c
+++ b/tests/gobject/references.c
@@ -256,7 +256,8 @@ main (int argc,
g_assert (object_destroyed == FALSE);
clear_flags ();
- g_object_remove_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24));
+ /* Check that removing a toggle ref with %NULL data works fine. */
+ g_object_remove_toggle_ref (object, toggle_ref2, NULL);
g_assert (toggle_ref1_weakened == FALSE);
g_assert (toggle_ref1_strengthened == FALSE);
g_assert (toggle_ref2_weakened == FALSE);
diff --git a/tests/gobject/testcommon.h b/tests/gobject/testcommon.h
index a5b59b3d3..3e40cca67 100644
--- a/tests/gobject/testcommon.h
+++ b/tests/gobject/testcommon.h
@@ -40,7 +40,8 @@ prefix ## _get_type (void) \
NULL, /* class_data */ \
sizeof (name), \
0, /* n_prelocs */ \
- (GInstanceInitFunc) instance_init \
+ (GInstanceInitFunc) instance_init, \
+ (const GTypeValueTable *) NULL, \
}; \
\
object_type = g_type_register_static (parent_type, \
@@ -72,6 +73,12 @@ prefix ## _get_type (void) \
(GBaseInitFunc) base_init, \
(GBaseFinalizeFunc) NULL, \
(GClassInitFunc) dflt_init, \
+ (GClassFinalizeFunc) NULL, \
+ (gconstpointer) NULL, \
+ (guint16) 0, \
+ (guint16) 0, \
+ (GInstanceInitFunc) NULL, \
+ (const GTypeValueTable*) NULL, \
}; \
\
iface_type = g_type_register_static (G_TYPE_INTERFACE, \
diff --git a/tests/gobject/testgobject.c b/tests/gobject/testgobject.c
index df7d4c748..e467abcd4 100644
--- a/tests/gobject/testgobject.c
+++ b/tests/gobject/testgobject.c
@@ -50,6 +50,13 @@ test_iface_get_type (void)
sizeof (TestIfaceClass),
(GBaseInitFunc) iface_base_init, /* base_init */
(GBaseFinalizeFunc) iface_base_finalize, /* base_finalize */
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL,
+ NULL
};
test_iface_type = g_type_register_static (G_TYPE_INTERFACE, "TestIface", &test_iface_info, 0);
@@ -178,7 +185,8 @@ test_object_get_type (void)
NULL, /* class_data */
sizeof (TestObject),
5, /* n_preallocs */
- (GInstanceInitFunc) test_object_init,
+ (GInstanceInitFunc) test_object_init,
+ NULL
};
GInterfaceInfo iface_info = { test_object_test_iface_init, NULL, GUINT_TO_POINTER (42) };
@@ -345,7 +353,8 @@ derived_object_get_type (void)
NULL, /* class_data */
sizeof (DerivedObject),
5, /* n_preallocs */
- (GInstanceInitFunc) derived_object_init,
+ (GInstanceInitFunc) derived_object_init,
+ NULL
};
GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
diff --git a/tests/gobject/timeloop-closure.c b/tests/gobject/timeloop-closure.c
index c904c2a45..51dd6f105 100644
--- a/tests/gobject/timeloop-closure.c
+++ b/tests/gobject/timeloop-closure.c
@@ -33,7 +33,7 @@ io_pipe (GIOChannel **channels)
}
static gboolean
-read_all (GIOChannel *channel, char *buf, int len)
+read_all (GIOChannel *channel, char *buf, gsize len)
{
gsize bytes_read = 0;
gsize count;
@@ -57,7 +57,7 @@ read_all (GIOChannel *channel, char *buf, int len)
}
static gboolean
-write_all (GIOChannel *channel, char *buf, int len)
+write_all (GIOChannel *channel, char *buf, gsize len)
{
gsize bytes_written = 0;
gsize count;
diff --git a/tests/mainloop-test.c b/tests/mainloop-test.c
index 5a3e6c989..be6024a10 100644
--- a/tests/mainloop-test.c
+++ b/tests/mainloop-test.c
@@ -352,10 +352,10 @@ create_crawler (void)
static void
cleanup_crawlers (GMainContext *context)
{
- gint i;
+ guint i;
G_LOCK (crawler_array_lock);
- for (i=0; i < crawler_array->len; i++)
+ for (i = 0; i < crawler_array->len; i++)
{
if (g_source_get_context (crawler_array->pdata[i]) == context)
{
diff --git a/tests/memchunks.c b/tests/memchunks.c
index fae7c4107..f574ed8b0 100644
--- a/tests/memchunks.c
+++ b/tests/memchunks.c
@@ -49,7 +49,7 @@ static guint mem_chunk_recursion = 0;
/* --- old memchunk prototypes --- */
GMemChunk* old_mem_chunk_new (const gchar *name,
- gint atom_size,
+ gulong atom_size,
gulong area_size,
gint type);
void old_mem_chunk_destroy (GMemChunk *mem_chunk);
@@ -129,7 +129,7 @@ static GMemChunk *mem_chunks = NULL;
GMemChunk*
old_mem_chunk_new (const gchar *name,
- gint atom_size,
+ gulong atom_size,
gulong area_size,
gint type)
{
diff --git a/tests/onceinit.c b/tests/onceinit.c
index 9788efcbd..4f30739ca 100644
--- a/tests/onceinit.c
+++ b/tests/onceinit.c
@@ -259,7 +259,7 @@ stress_concurrent_initializers (void *user_data)
LIST_256_TEST_INITIALIZERS (stress3),
LIST_256_TEST_INITIALIZERS (stress4),
};
- int i;
+ gsize i;
/* sync to main thread */
g_mutex_lock (&tmutex);
g_mutex_unlock (&tmutex);
diff --git a/tests/refcount/objects.c b/tests/refcount/objects.c
index 0c471a42b..06b871936 100644
--- a/tests/refcount/objects.c
+++ b/tests/refcount/objects.c
@@ -115,7 +115,7 @@ run_thread (GTest * test)
int
main (int argc, char **argv)
{
- gint i;
+ guint i;
GTest *test1, *test2;
GArray *test_threads;
const guint n_threads = 5;
diff --git a/tests/slice-threadinit.c b/tests/slice-threadinit.c
index f29dcbed1..e303aa0b2 100644
--- a/tests/slice-threadinit.c
+++ b/tests/slice-threadinit.c
@@ -31,7 +31,7 @@
static struct {
void *page;
void *sample;
-} pages[N_PAGES] = { { NULL, }, };
+} pages[N_PAGES] = { { NULL, NULL }, };
static const guint magazine_probes[] = MAGAZINE_PROBES;
#define N_MAGAZINE_PROBES G_N_ELEMENTS (magazine_probes)
@@ -70,7 +70,7 @@ int
main (int argc,
char *argv[])
{
- int j, n_pages = 0;
+ gsize j, n_pages = 0;
void *mps[N_MAGAZINE_PROBES];
/* probe some magazine sizes */
diff --git a/tests/testgdate.c b/tests/testgdate.c
index cc1e7a972..371d8addf 100644
--- a/tests/testgdate.c
+++ b/tests/testgdate.c
@@ -27,7 +27,9 @@ if (failed) \
} \
else \
++passed; \
- if ((passed+notpassed) % 10000 == 0) g_print ("."); fflush (stdout); \
+if ((passed+notpassed) % 10000 == 0) \
+ g_print ("."); \
+fflush (stdout); \
} G_STMT_END
static void
diff --git a/tests/testglib.c b/tests/testglib.c
index 86c807922..071afdc1d 100644
--- a/tests/testglib.c
+++ b/tests/testglib.c
@@ -78,7 +78,7 @@ static void
glist_test (void)
{
GList *list = NULL;
- guint i;
+ gint i;
for (i = 0; i < 10; i++)
list = g_list_append (list, &test_nums[i]);
@@ -158,7 +158,7 @@ static void
gslist_test (void)
{
GSList *slist = NULL;
- guint i;
+ gint i;
for (i = 0; i < 10; i++)
slist = g_slist_append (slist, &test_nums[i]);
@@ -299,11 +299,11 @@ gnode_test (void)
for (i = 0; i < g_node_n_children (node_B); i++)
{
node = g_node_nth_child (node_B, i);
- g_assert (P2C (node->data) == ('C' + i));
+ g_assert (P2C (node->data) == (gchar) ('C' + i));
}
for (i = 0; i < g_node_n_children (node_G); i++)
- g_assert (g_node_child_position (node_G, g_node_nth_child (node_G, i)) == i);
+ g_assert (g_node_child_position (node_G, g_node_nth_child (node_G, i)) == (gint) i);
/* we have built: A
* / \
@@ -1313,7 +1313,7 @@ test_arrays (void)
for (i = 0; i < 10000; i++)
g_array_append_val (garray, i);
for (i = 0; i < 10000; i++)
- if (g_array_index (garray, gint, i) != i)
+ if (g_array_index (garray, gint, i) != (gint) i)
g_error ("failure: %d ( %d )", g_array_index (garray, gint, i), i);
g_array_free (garray, TRUE);
@@ -1321,7 +1321,7 @@ test_arrays (void)
for (i = 0; i < 100; i++)
g_array_prepend_val (garray, i);
for (i = 0; i < 100; i++)
- if (g_array_index (garray, gint, i) != (100 - i - 1))
+ if (g_array_index (garray, gint, i) != (gint) (100 - i - 1))
g_error ("failure: %d ( %d )", g_array_index (garray, gint, i), 100 - i - 1);
g_array_free (garray, TRUE);
}
diff --git a/tests/thread-test.c b/tests/thread-test.c
index 17ac41f7b..883aa5424 100644
--- a/tests/thread-test.c
+++ b/tests/thread-test.c
@@ -211,7 +211,7 @@ test_g_static_private (void)
test_g_static_private_ready = 0;
for (i = 0; i < THREADS; i++)
- g_assert (GPOINTER_TO_INT (g_thread_join (threads[i])) == i * 3);
+ g_assert (GPOINTER_TO_UINT (g_thread_join (threads[i])) == i * 3);
g_assert (test_g_static_private_counter == 0);
}
diff --git a/tests/threadpool-test.c b/tests/threadpool-test.c
index dfd138212..1612e274e 100644
--- a/tests/threadpool-test.c
+++ b/tests/threadpool-test.c
@@ -248,7 +248,7 @@ test_thread_sort (gboolean sort)
GThreadPool *pool;
guint limit;
guint max_threads;
- gint i;
+ guint i;
limit = MAX_THREADS * 10;
@@ -293,8 +293,8 @@ test_thread_sort (gboolean sort)
g_thread_pool_unprocessed (pool)));
}
- g_assert (g_thread_pool_get_max_threads (pool) == max_threads);
- g_assert (g_thread_pool_get_num_threads (pool) == g_thread_pool_get_max_threads (pool));
+ g_assert (g_thread_pool_get_max_threads (pool) == (gint) max_threads);
+ g_assert (g_thread_pool_get_num_threads (pool) == (guint) g_thread_pool_get_max_threads (pool));
g_thread_pool_free (pool, TRUE, TRUE);
}
@@ -337,7 +337,7 @@ test_thread_idle_time (void)
{
guint limit = 50;
guint interval = 10000;
- gint i;
+ guint i;
idle_pool = g_thread_pool_new (test_thread_idle_time_entry_func,
NULL,
diff --git a/tests/timeloop.c b/tests/timeloop.c
index 8b5aa3641..40064a140 100644
--- a/tests/timeloop.c
+++ b/tests/timeloop.c
@@ -32,7 +32,7 @@ io_pipe (GIOChannel **channels)
}
static gboolean
-read_all (GIOChannel *channel, char *buf, int len)
+read_all (GIOChannel *channel, char *buf, gsize len)
{
gsize bytes_read = 0;
gsize count;
@@ -56,7 +56,7 @@ read_all (GIOChannel *channel, char *buf, int len)
}
static gboolean
-write_all (GIOChannel *channel, char *buf, int len)
+write_all (GIOChannel *channel, char *buf, gsize len)
{
gsize bytes_written = 0;
gsize count;
diff --git a/tests/unicode-collate.c b/tests/unicode-collate.c
index b276a2f67..8de3f60ca 100644
--- a/tests/unicode-collate.c
+++ b/tests/unicode-collate.c
@@ -74,7 +74,7 @@ int main (int argc, char **argv)
}
}
- if (argc > i)
+ if (argc > (gint) i)
{
in = g_io_channel_new_file (argv[i], "r", &error);
if (!in)
diff --git a/tests/unicode-encoding.c b/tests/unicode-encoding.c
index c729b284d..b0603d105 100644
--- a/tests/unicode-encoding.c
+++ b/tests/unicode-encoding.c
@@ -137,7 +137,7 @@ process (gint line,
ucs4_result = g_utf8_to_ucs4 (utf8, -1, &items_read, NULL, &error);
- if (!ucs4_result || items_read == strlen (utf8))
+ if (!ucs4_result || items_read == (glong) strlen (utf8))
{
fail ("line %d: incomplete input not properly detected\n", line);
return;
@@ -158,7 +158,7 @@ process (gint line,
}
if (!ucs4_equal (ucs4_result, ucs4) ||
- items_read != strlen (utf8) ||
+ items_read != (glong) strlen (utf8) ||
items_written != ucs4_len)
{
fail ("line %d: results of conversion with status %d to ucs4 do not match expected.\n", line, status);
@@ -195,7 +195,7 @@ process (gint line,
if (strcmp (utf8_result, utf8) != 0 ||
items_read != ucs4_len ||
- items_written != strlen (utf8))
+ items_written != (glong) strlen (utf8))
{
fail ("line %d: conversion back to utf8 did not match original\n", line);
return;
@@ -257,7 +257,7 @@ process (gint line,
return;
}
- if (items_read != strlen (utf8) ||
+ if (items_read != (glong) strlen (utf8) ||
utf16_count (utf16_from_utf8) != items_written)
{
fail ("line %d: length error in conversion to ucs16\n", line);
@@ -291,7 +291,7 @@ process (gint line,
}
if (items_read != utf16_count (utf16_from_utf8) ||
- items_written != strlen (utf8))
+ items_written != (glong) strlen (utf8))
{
fail ("line %d: length error in conversion from ucs16 to utf8\n", line);
return;