diff options
author | ryoon <ryoon@pkgsrc.org> | 2014-03-30 04:13:17 +0000 |
---|---|---|
committer | ryoon <ryoon@pkgsrc.org> | 2014-03-30 04:13:17 +0000 |
commit | 639854a5fba15fde1bd474281b1dc1da19f6a88c (patch) | |
tree | 82c5f8d24f4c4c7c3d136682773bd33c1277c7b6 /www/seamonkey/patches | |
parent | f65969568438b2bffae675f644532c9b02269a78 (diff) | |
download | pkgsrc-639854a5fba15fde1bd474281b1dc1da19f6a88c.tar.gz |
Update to 2.25
* Change enigmail build mechanism
Changelog:
2.25:
SeaMonkey-specific changes
Newsgroup names can now be entered using autocompletion.
See the changes page for a more complete overview.
Mozilla platform changes
The Gamepad API has been finalized and enabled (learn more).
VP9 video decoding has been implemented.
Support for Opus in WebM was added.
Volume control for HTML5 audio/video has been added.
Mac OS X Notification Center support has been added for web notifications.
Support for spdy/2 has been removed.
Support for multi-line flexbox in layout has been added.
Support for the MathML 2.0 mathvariant attribute has been added.
Background thread hang reporting has been added.
<input type=color> has been implemented and enabled.
Fixed several stability issues.
Fixed in SeaMonkey 2.25
MFSA 2014-32 Out-of-bounds write through TypedArrayObject after neutering
MFSA 2014-31 Out-of-bounds read/write through neutering ArrayBuffer objects
MFSA 2014-30 Use-after-free in TypeObject
MFSA 2014-29 Privilege escalation using WebIDL-implemented APIs
MFSA 2014-28 SVG filters information disclosure through feDisplacementMap
MFSA 2014-27 Memory corruption in Cairo during PDF font rendering
MFSA 2014-26 Information disclosure through polygon rendering in MathML
MFSA 2014-23 Content Security Policy for data: documents not preserved by session restore
MFSA 2014-22 WebGL content injection from one domain to rendering in another
MFSA 2014-20 onbeforeunload and Javascript navigation DOS
MFSA 2014-19 Spoofing attack on WebRTC permission prompt
MFSA 2014-18 crypto.generateCRMFRequest does not validate type of key
MFSA 2014-17 Out of bounds read during WAV file decoding
MFSA 2014-16 Files extracted during updates are not always read only
MFSA 2014-15 Miscellaneous memory safety hazards (rv:28.0 / rv:24.4)
2.24:
SeaMonkey-specific changes
The DoNotTrack and Prompt on Sanitize preferences are now kept in sync.
A pref (mailnews.p7m_external) has been added to allow users to choose an alternate application/pkcs7-mime handling.
Support for Atom Threading Extensions (RFC 4685) has been added.
Migrating profiles from Thunderbird supports the new signons file format now (support for the old format has been dropped).
Autocomplete drop-downs (e.g. used on the Location Bar and Open Location dialog) now show favicons for their entries.
The account name is now displayed in the status bar for all messages when checking mail.
IMAP alert messages now show the server of the corresponding mail account.
Newsgroup names are now searched for all search strings combined (AND-search) on the subscribe dialog.
See the changes page for a more complete overview.
Mozilla platform changes
Removed support for importing logins from the legacy signons.txt format, including the Base64 conversion (bug 717490).
Enabled support for TLS 1.2 (RFC 5246) by default (bug 861266).
Added support for the SPDY 3.1 protocol.
Added ability to reset style sheets using all:unset.
Added support for scrolled fieldsets (overflow property support, bug 261037).
Implemented allow-popups directive for iframe sandbox, enabling increased security (bug 766282).
Unprefixed CSS cursor keywords -moz-grab and -moz-grabbing (bug 880672).
Added support for ES6 generators in SpiderMonkey (blog post).
Implemented support for mathematical function Math.hypot() in ES6 (bug 896264).
Added dashed line support on Canvas (bug 768067).
Fixed Azure/Skia content rendering on Linux (bug 740200).
Fixed several stability issues.
Fixed in SeaMonkey 2.24
MFSA 2014-13 Inconsistent JavaScript handling of access to Window objects
MFSA 2014-12 NSS ticket handling issues
MFSA 2014-11 Crash when using web workers with asm.js
MFSA 2014-09 Cross-origin information leak through web workers
MFSA 2014-08 Use-after-free with imgRequestProxy and image proccessing
MFSA 2014-07 XSLT stylesheets treated as styles in Content Security Policy
MFSA 2014-05 Information disclosure with *FromPoint on iframes
MFSA 2014-04 Incorrect use of discarded images by RasterImage
MFSA 2014-03 UI selection timeout missing on download prompts
MFSA 2014-02 Clone protected content with XBL scopes
MFSA 2014-01 Miscellaneous memory safety hazards (rv:27.0 / rv:24.3)
Diffstat (limited to 'www/seamonkey/patches')
73 files changed, 3094 insertions, 4352 deletions
diff --git a/www/seamonkey/patches/patch-aa b/www/seamonkey/patches/patch-aa index 6f4d4a665c0..b802156ccf3 100644 --- a/www/seamonkey/patches/patch-aa +++ b/www/seamonkey/patches/patch-aa @@ -1,51 +1,134 @@ -$NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-aa,v 1.21 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/configure.in.orig 2013-12-11 04:28:28.000000000 +0000 +--- mozilla/configure.in.orig 2014-03-19 01:41:46.000000000 +0000 +++ mozilla/configure.in -@@ -2752,6 +2752,7 @@ EOF - #pragma GCC visibility push(hidden) - #pragma GCC visibility push(default) - #include <string.h> -+#include <iterator> - #pragma GCC visibility pop - - __attribute__ ((visibility ("default"))) void Func() { -@@ -2760,7 +2761,7 @@ __attribute__ ((visibility ("default"))) - } - EOF - ac_cv_have_visibility_builtin_bug=no +@@ -2544,118 +2544,15 @@ MOZ_CXX11 + + AC_LANG_C + +-dnl Check for .hidden assembler directive and visibility attribute. +-dnl Borrowed from glibc configure.in ++dnl Setup default hidden visibility and wrapped system headers. + dnl =============================================================== + if test "$GNU_CC"; then +- AC_CACHE_CHECK(for visibility(hidden) attribute, +- ac_cv_visibility_hidden, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("hidden"))) = 1; +-EOF +- ac_cv_visibility_hidden=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_hidden=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_hidden" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility(default) attribute, +- ac_cv_visibility_default, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("default"))) = 1; +-EOF +- ac_cv_visibility_default=no +- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_default=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_default" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility pragma support, +- ac_cv_visibility_pragma, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +- int foo_hidden = 1; +-#pragma GCC visibility push(default) +- int foo_default = 1; +-EOF +- ac_cv_visibility_pragma=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then +- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then +- ac_cv_visibility_pragma=yes +- fi +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_pragma" = "yes"; then +- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905), +- ac_cv_have_visibility_class_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-struct __attribute__ ((visibility ("default"))) TestStruct { +- static void Init(); +-}; +-__attribute__ ((visibility ("default"))) void TestFunc() { +- TestStruct::Init(); +-} +-EOF +- ac_cv_have_visibility_class_bug=no +- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then +- ac_cv_have_visibility_class_bug=yes +- else +- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then +- ac_cv_have_visibility_class_bug=yes +- fi +- fi +- rm -rf conftest.{c,S} +- ]) +- +- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297), +- ac_cv_have_visibility_builtin_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-#pragma GCC visibility push(default) +-#include <string.h> +-#pragma GCC visibility pop +- +-__attribute__ ((visibility ("default"))) void Func() { +- char c[[100]]; +- memset(c, 0, sizeof(c)); +-} +-EOF +- ac_cv_have_visibility_builtin_bug=no - if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then -+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then - ac_cv_have_visibility_builtin_bug=yes - else - if test `grep -c "@PLT" conftest.S` = 0; then -@@ -3216,14 +3217,22 @@ fi - AC_CACHE_CHECK( - [for res_ninit()], - ac_cv_func_res_ninit, -- [AC_TRY_LINK([ -+ [AC_TRY_RUN([ - #ifdef linux - #define _BSD_SOURCE 1 - #endif -+ #ifdef __NetBSD__ -+ #error use of global _res variable in threaded programs is not portable -+ #endif -+ #include <sys/types.h> -+ #include <netinet/in.h> -+ #include <arpa/nameser.h> - #include <resolv.h> -- ], -- [int foo = res_ninit(&_res);], -+ int main(int argc, char **argv){ -+ int foo = res_ninit(&_res); -+ }], - [ac_cv_func_res_ninit=yes], -+ [ac_cv_func_res_ninit=no], - [ac_cv_func_res_ninit=no]) - ]) - -@@ -3874,6 +3883,14 @@ if test -n "$YASM"; then +- ac_cv_have_visibility_builtin_bug=yes +- else +- if test `grep -c "@PLT" conftest.S` = 0; then +- ac_cv_visibility_builtin_bug=yes +- fi +- fi +- rm -f conftest.{c,S} +- ]) +- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ +- "$ac_cv_have_visibility_class_bug" = "no"; then +- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' +- WRAP_SYSTEM_INCLUDES=1 +- STL_FLAGS='-I$(DIST)/stl_wrappers' +- WRAP_STL_INCLUDES=1 +- else +- VISIBILITY_FLAGS='-fvisibility=hidden' +- fi # have visibility pragma bug +- fi # have visibility pragma +- fi # have visibility(default) attribute +- fi # have visibility(hidden) attribute ++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) ++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) ++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' ++ WRAP_SYSTEM_INCLUDES=1 ++ STL_FLAGS='-I$(DIST)/stl_wrappers' ++ WRAP_STL_INCLUDES=1 + fi # GNU_CC + + # visibility hidden flag for Sun Studio on Solaris +@@ -3724,6 +3621,14 @@ if test -n "$YASM"; then _YASM_BUILD=` echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'` fi @@ -60,7 +143,7 @@ $NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ if test -z "$SKIP_LIBRARY_CHECKS"; then dnl system JPEG support dnl ======================================================== -@@ -3901,11 +3918,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then +@@ -3751,11 +3656,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then #include <jpeglib.h> ], [ #if JPEG_LIB_VERSION < $MOZJPEG #error "Insufficient JPEG library version ($MOZJPEG required)." @@ -73,7 +156,7 @@ $NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ MOZ_NATIVE_JPEG=1, AC_MSG_ERROR([Insufficient JPEG library version for --with-system-jpeg])) fi -@@ -4062,6 +4075,22 @@ fi +@@ -3921,6 +3822,22 @@ fi AC_SUBST(MOZ_NATIVE_ICU) dnl ======================================================== @@ -96,20 +179,25 @@ $NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ dnl Java SDK support dnl ======================================================== -@@ -5281,6 +5310,12 @@ if test -n "$MOZ_WEBRTC"; then - MOZ_VP8_ENCODER=1 +@@ -3955,6 +3872,7 @@ MOZ_SAMPLE_TYPE_FLOAT32= + MOZ_SAMPLE_TYPE_S16= + MOZ_OPUS=1 + MOZ_WEBM=1 ++MOZ_GSTREAMER= + MOZ_DIRECTSHOW= + MOZ_WMF= + MOZ_FMP4= +@@ -5136,6 +5054,9 @@ if test -n "$MOZ_WEBRTC"; then + MOZ_VP8=1 MOZ_VP8_ERROR_CONCEALMENT=1 + dnl with libv4l2 we can support more cameras + PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2) + -+ dnl with libv4l2 we can support more cameras -+ PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2) -+ dnl enable once Signaling lands MOZ_WEBRTC_SIGNALING=1 AC_DEFINE(MOZ_WEBRTC_SIGNALING) -@@ -5307,15 +5342,18 @@ AC_SUBST(MOZ_SRTP) +@@ -5158,15 +5079,18 @@ AC_SUBST(MOZ_SRTP) dnl Use integers over floats for audio on B2G and Android, because audio dnl backends for those platforms don't support floats. @@ -131,7 +219,205 @@ $NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ dnl ======================================================== dnl = Disable Speech API code -@@ -8276,7 +8314,7 @@ case "$OS_TARGET" in +@@ -5230,6 +5154,40 @@ if test -n "$MOZ_OGG"; then + fi + + dnl ======================================================== ++dnl Check for libogg ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-ogg, ++[ --with-system-ogg Use system libogg (located with pkgconfig)], ++MOZ_NATIVE_OGG=1, ++MOZ_NATIVE_OGG= ) ++ ++if test -n "$MOZ_NATIVE_OGG"; then ++ PKG_CHECK_MODULES(MOZ_OGG, ogg >= 1.2.1) ++fi ++ ++AC_SUBST(MOZ_NATIVE_OGG) ++AC_SUBST(MOZ_OGG_CFLAGS) ++AC_SUBST(MOZ_OGG_LIBS) ++ ++dnl ======================================================== ++dnl Check for libvorbis ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-vorbis, ++[ --with-system-vorbis Use system libvorbis (located with pkgconfig)], ++MOZ_NATIVE_VORBIS=1, ++MOZ_NATIVE_VORBIS= ) ++ ++if test -n "$MOZ_NATIVE_VORBIS"; then ++ PKG_CHECK_MODULES(MOZ_VORBIS, vorbis vorbisenc >= 1.3.4) ++fi ++ ++AC_SUBST(MOZ_NATIVE_VORBIS) ++AC_SUBST(MOZ_VORBIS_CFLAGS) ++AC_SUBST(MOZ_VORBIS_LIBS) ++ ++dnl ======================================================== + dnl = Disable Opus audio codec support + dnl ======================================================== + MOZ_ARG_DISABLE_BOOL(opus, +@@ -5238,6 +5196,25 @@ MOZ_ARG_DISABLE_BOOL(opus, + MOZ_OPUS=1) + + dnl ======================================================== ++dnl Check for libopus ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-opus, ++[ --with-system-opus Use system libopus (located with pkgconfig)], ++MOZ_NATIVE_OPUS=1, ++MOZ_NATIVE_OPUS= ) ++ ++if test -n "$MOZ_NATIVE_OPUS"; then ++ PKG_CHECK_MODULES(MOZ_OPUS, opus >= 1.1) ++else ++ MOZ_OPUS_CFLAGS='-I$(topsrcdir)/media/libopus/include' ++fi ++ ++AC_SUBST(MOZ_NATIVE_OPUS) ++AC_SUBST(MOZ_OPUS_CFLAGS) ++AC_SUBST(MOZ_OPUS_LIBS) ++ ++dnl ======================================================== + dnl = Disable VP8 decoder support + dnl ======================================================== + MOZ_ARG_DISABLE_BOOL(webm, +@@ -5606,43 +5583,60 @@ dnl = Enable GStreamer + dnl ======================================================== + if test "$OS_TARGET" = "Linux"; then + MOZ_GSTREAMER=1 ++ GST_API_VERSION=0.10 + fi + +-MOZ_ARG_ENABLE_BOOL(gstreamer, +-[ --enable-gstreamer Enable GStreamer support], +-MOZ_GSTREAMER=1, +-MOZ_GSTREAMER=) +- +-if test "$MOZ_GSTREAMER"; then +- # API version, eg 0.10, 1.0 etc ++MOZ_ARG_ENABLE_STRING(gstreamer, ++[ --enable-gstreamer[=0.10] Enable GStreamer support], ++[ MOZ_GSTREAMER=1 ++ # API version, eg 0.10, 1.0 etc ++ if test -z "$enableval" -o "$enableval" = "yes"; then + GST_API_VERSION=0.10 ++ elif test "$enableval" = "no"; then ++ MOZ_GSTREAMER= ++ else ++ GST_API_VERSION=$enableval ++ fi], ++) ++ ++if test -n "$MOZ_GSTREAMER"; then + # core/base release number +- GST_VERSION=0.10.25 ++ if test "$GST_API_VERSION" = "1.0"; then ++ GST_VERSION=1.0 ++ else ++ GST_VERSION=0.10.25 ++ fi ++ + PKG_CHECK_MODULES(GSTREAMER, + gstreamer-$GST_API_VERSION >= $GST_VERSION + gstreamer-app-$GST_API_VERSION +- gstreamer-plugins-base-$GST_API_VERSION, , +- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])) +- if test -n "$GSTREAMER_LIBS"; then +- _SAVE_LDFLAGS=$LDFLAGS +- LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" +- AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) +- if test -n "$_HAVE_LIBGSTVIDEO" ; then +- GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" +- else +- AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) +- fi +- LDFLAGS=$_SAVE_LDFLAGS ++ gstreamer-plugins-base-$GST_API_VERSION, ++ [_HAVE_GSTREAMER=1], ++ [_HAVE_GSTREAMER=]) ++ if test -z "$_HAVE_GSTREAMER"; then ++ AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) ++ fi ++ ++ _SAVE_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" ++ AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) ++ if test -n "$_HAVE_LIBGSTVIDEO" ; then ++ GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" + else +- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) ++ AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) + fi ++ LDFLAGS=$_SAVE_LDFLAGS ++ ++ AC_SUBST(GSTREAMER_CFLAGS) ++ AC_SUBST(GSTREAMER_LIBS) + fi +-AC_SUBST(GSTREAMER_CFLAGS) +-AC_SUBST(GSTREAMER_LIBS) ++ + AC_SUBST(MOZ_GSTREAMER) ++AC_SUBST(GST_API_VERSION) + + if test -n "$MOZ_GSTREAMER"; then +- AC_DEFINE(MOZ_GSTREAMER) ++ AC_DEFINE(MOZ_GSTREAMER) ++ AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION") + fi + + +@@ -7424,7 +7418,10 @@ dnl ==================================== + dnl = Support for gcc stack unwinding (from gcc 3.3) + dnl ======================================================== + if test -z "$SKIP_LIBRARY_CHECKS"; then ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS + MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace)) ++ AC_LANG_RESTORE + fi + + dnl ======================================================== +@@ -7870,6 +7867,34 @@ if test "$USE_FC_FREETYPE"; then + fi + + dnl ======================================================== ++dnl Check for graphite2 and harfbuzz ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-harfbuzz, ++[ --with-system-harfbuzz Use system harfbuzz (located with pkgconfig)], ++MOZ_NATIVE_HARFBUZZ=1, ++MOZ_NATIVE_HARFBUZZ= ) ++ ++if test -n "$MOZ_NATIVE_HARFBUZZ"; then ++ PKG_CHECK_MODULES(MOZ_HARFBUZZ, harfbuzz >= 0.9.25) ++fi ++AC_SUBST(MOZ_NATIVE_HARFBUZZ) ++AC_SUBST(MOZ_HARFBUZZ_CFLAGS) ++AC_SUBST(MOZ_HARFBUZZ_LIBS) ++ ++MOZ_ARG_WITH_BOOL(system-graphite2, ++[ --with-system-graphite2 Use system graphite2 (located with pkgconfig)], ++MOZ_NATIVE_GRAPHITE2=1, ++MOZ_NATIVE_GRAPHITE2= ) ++ ++if test -n "$MOZ_NATIVE_GRAPHITE2"; then ++ PKG_CHECK_MODULES(MOZ_GRAPHITE2, graphite2 >= 1.2.4) ++fi ++AC_SUBST(MOZ_NATIVE_GRAPHITE2) ++AC_SUBST(MOZ_GRAPHITE2_CFLAGS) ++AC_SUBST(MOZ_GRAPHITE2_LIBS) ++ ++dnl ======================================================== + dnl Check for pixman and cairo + dnl ======================================================== + +@@ -8118,7 +8143,7 @@ case "$OS_TARGET" in NECKO_WIFI=1 fi ;; @@ -140,14 +426,31 @@ $NetBSD: patch-aa,v 1.20 2013/12/26 13:17:37 ryoon Exp $ NECKO_WIFI=1 ;; Linux) -@@ -9005,6 +9043,14 @@ if test -n "$INTEL_ARCHITECTURE"; then - fi - fi +@@ -8665,6 +8690,20 @@ AC_SUBST(MOZ_ENABLE_SZIP) + AC_SUBST(MOZ_SZIP_FLAGS) -+if test -n "$MOZ_LIBV4L2_LIBS"; then -+ EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1" + if test -n "$COMPILE_ENVIRONMENT"; then ++AC_MSG_CHECKING([for posix_fadvise]) ++AC_TRY_LINK([#define _XOPEN_SOURCE 600 ++ #include <fcntl.h>], ++ [posix_fadvise(0, 0, 0, 0);], ++ [ac_cv___posix_fadvise=true], ++ [ac_cv___posix_fadvise=false]) ++ ++if test "$ac_cv___posix_fadvise" = true ; then ++ AC_DEFINE(HAVE_POSIX_FADVISE) ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) +fi + + AC_MSG_CHECKING([for posix_fallocate]) + AC_TRY_LINK([#define _XOPEN_SOURCE 600 + #include <fcntl.h>], +@@ -8918,6 +8957,10 @@ if test -n "$INTEL_ARCHITECTURE"; then + fi + fi + +if test -n "$MOZ_LIBV4L2_LIBS"; then + EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1" +fi diff --git a/www/seamonkey/patches/patch-ao b/www/seamonkey/patches/patch-ao index 1101ae189b0..cf8b2b62f31 100644 --- a/www/seamonkey/patches/patch-ao +++ b/www/seamonkey/patches/patch-ao @@ -1,16 +1,12 @@ -$NetBSD: patch-ao,v 1.13 2013/11/04 06:01:46 ryoon Exp $ +$NetBSD: patch-ao,v 1.14 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/toolkit/mozapps/installer/packager.mk.orig 2013-10-29 01:21:13.000000000 +0000 +--- mozilla/toolkit/mozapps/installer/packager.mk.orig 2014-03-19 01:42:17.000000000 +0000 +++ mozilla/toolkit/mozapps/installer/packager.mk -@@ -680,9 +680,9 @@ endif - (cd $(DIST)/$(MOZ_PKG_DIR) && $(TAR) --exclude=precomplete $(TAR_CREATE_FLAGS) - .) | \ - (cd $(DESTDIR)$(installdir) && tar -xf -) +@@ -775,7 +775,7 @@ endif $(NSINSTALL) -D $(DESTDIR)$(bindir) -- $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME) -- ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir) + $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME) + ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir) -ifdef INSTALL_SDK # Here comes the hard part -+ $(RM) -f $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME) -+ ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME) +ifeq ($(MOZ_APP_NAME),xulrunner) $(NSINSTALL) -D $(DESTDIR)$(includedir) (cd $(DIST)/include && $(TAR) $(TAR_CREATE_FLAGS) - .) | \ diff --git a/www/seamonkey/patches/patch-as b/www/seamonkey/patches/patch-as index c153d027e2f..379a0b1a53a 100644 --- a/www/seamonkey/patches/patch-as +++ b/www/seamonkey/patches/patch-as @@ -1,28 +1,133 @@ -$NetBSD: patch-as,v 1.15 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-as,v 1.16 2014/03/30 04:13:17 ryoon Exp $ * Fix _res is not supported for multi-threaded programs. error. * Treat DragonFly like FreeBSD. ---- mozilla/js/src/configure.in.orig 2013-12-11 04:28:40.000000000 +0000 +--- mozilla/js/src/configure.in.orig 2014-03-19 01:41:57.000000000 +0000 +++ mozilla/js/src/configure.in -@@ -2290,6 +2290,7 @@ EOF - #pragma GCC visibility push(hidden) - #pragma GCC visibility push(default) - #include <string.h> -+#include <iterator> - #pragma GCC visibility pop +@@ -2148,116 +2148,13 @@ AC_LANG_CPLUSPLUS - __attribute__ ((visibility ("default"))) void Func() { -@@ -2298,7 +2299,7 @@ __attribute__ ((visibility ("default"))) - } - EOF - ac_cv_have_visibility_builtin_bug=no + MOZ_CXX11 + +-dnl Check for .hidden assembler directive and visibility attribute. +-dnl Borrowed from glibc configure.in ++dnl Setup default hidden visibility and wrapped system headers. + dnl =============================================================== + if test "$GNU_CC"; then +- AC_CACHE_CHECK(for visibility(hidden) attribute, +- ac_cv_visibility_hidden, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("hidden"))) = 1; +-EOF +- ac_cv_visibility_hidden=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_hidden=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_hidden" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility(default) attribute, +- ac_cv_visibility_default, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("default"))) = 1; +-EOF +- ac_cv_visibility_default=no +- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_default=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_default" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility pragma support, +- ac_cv_visibility_pragma, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +- int foo_hidden = 1; +-#pragma GCC visibility push(default) +- int foo_default = 1; +-EOF +- ac_cv_visibility_pragma=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then +- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then +- ac_cv_visibility_pragma=yes +- fi +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_pragma" = "yes"; then +- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905), +- ac_cv_have_visibility_class_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-struct __attribute__ ((visibility ("default"))) TestStruct { +- static void Init(); +-}; +-__attribute__ ((visibility ("default"))) void TestFunc() { +- TestStruct::Init(); +-} +-EOF +- ac_cv_have_visibility_class_bug=no +- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then +- ac_cv_have_visibility_class_bug=yes +- else +- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then +- ac_cv_have_visibility_class_bug=yes +- fi +- fi +- rm -rf conftest.{c,S} +- ]) +- +- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297), +- ac_cv_have_visibility_builtin_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-#pragma GCC visibility push(default) +-#include <string.h> +-#pragma GCC visibility pop +- +-__attribute__ ((visibility ("default"))) void Func() { +- char c[[100]]; +- memset(c, 0, sizeof(c)); +-} +-EOF +- ac_cv_have_visibility_builtin_bug=no - if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then -+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then - ac_cv_have_visibility_builtin_bug=yes - else - if test `grep -c "@PLT" conftest.S` = 0; then -@@ -2515,7 +2516,7 @@ then +- ac_cv_have_visibility_builtin_bug=yes +- else +- if test `grep -c "@PLT" conftest.S` = 0; then +- ac_cv_visibility_builtin_bug=yes +- fi +- fi +- rm -f conftest.{c,S} +- ]) +- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ +- "$ac_cv_have_visibility_class_bug" = "no"; then +- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' +- WRAP_SYSTEM_INCLUDES=1 +- else +- VISIBILITY_FLAGS='-fvisibility=hidden' +- fi # have visibility pragma bug +- fi # have visibility pragma +- fi # have visibility(default) attribute +- fi # have visibility(hidden) attribute ++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) ++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) ++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' ++ WRAP_SYSTEM_INCLUDES=1 + fi # GNU_CC + + # visibility hidden flag for Sun Studio on Solaris +@@ -2456,7 +2353,7 @@ then fi case "$target" in @@ -31,33 +136,7 @@ $NetBSD: patch-as,v 1.15 2013/12/26 13:17:37 ryoon Exp $ AC_DEFINE(_REENTRANT) AC_DEFINE(_THREAD_SAFE) dnl -pthread links in -lpthread, so don't specify it explicitly. -@@ -2600,14 +2601,22 @@ fi - AC_CACHE_CHECK( - [for res_ninit()], - ac_cv_func_res_ninit, -- [AC_TRY_LINK([ -+ [AC_TRY_RUN([ - #ifdef linux - #define _BSD_SOURCE 1 - #endif -+ #ifdef __NetBSD__ -+ #error use of global _res variable in threaded programs is not portable -+ #endif -+ #include <sys/types.h> -+ #include <netinet/in.h> -+ #include <arpa/nameser.h> - #include <resolv.h> -- ], -- [int foo = res_ninit(&_res);], -+ int main(int argc, char **argv){ -+ int foo = res_ninit(&_res); -+ }], - [ac_cv_func_res_ninit=yes], -+ [ac_cv_func_res_ninit=no], - [ac_cv_func_res_ninit=no]) - ]) - -@@ -3316,7 +3325,7 @@ if test "$MOZ_MEMORY"; then +@@ -3270,7 +3167,7 @@ if test "$MOZ_MEMORY"; then *-darwin*) AC_DEFINE(MOZ_MEMORY_DARWIN) ;; @@ -66,7 +145,39 @@ $NetBSD: patch-as,v 1.15 2013/12/26 13:17:37 ryoon Exp $ AC_DEFINE(MOZ_MEMORY_BSD) ;; *-android*|*-linuxandroid*) -@@ -4339,6 +4348,16 @@ fi +@@ -3632,7 +3529,10 @@ dnl ==================================== + dnl = Support for gcc stack unwinding (from gcc 3.3) + dnl ======================================================== + if test -z "$SKIP_LIBRARY_CHECKS"; then ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS + MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace)) ++ AC_LANG_RESTORE + fi + + dnl ======================================================== +@@ -4086,6 +3986,20 @@ AC_SUBST(CXX_VERSION) + AC_SUBST(MSMANIFEST_TOOL) + AC_SUBST(MOZ_LINKER) + ++AC_MSG_CHECKING([for posix_fadvise]) ++AC_TRY_LINK([#define _XOPEN_SOURCE 600 ++ #include <fcntl.h>], ++ [posix_fadvise(0, 0, 0, 0);], ++ [ac_cv___posix_fadvise=true], ++ [ac_cv___posix_fadvise=false]) ++ ++if test "$ac_cv___posix_fadvise" = true ; then ++ AC_DEFINE(HAVE_POSIX_FADVISE) ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) ++fi ++ + AC_MSG_CHECKING([for posix_fallocate]) + AC_TRY_LINK([#define _XOPEN_SOURCE 600 + #include <fcntl.h>], +@@ -4436,6 +4350,16 @@ fi dnl ======================================================== dnl JavaScript shell dnl ======================================================== diff --git a/www/seamonkey/patches/patch-mb b/www/seamonkey/patches/patch-mb index b20851d32c1..c647908572d 100644 --- a/www/seamonkey/patches/patch-mb +++ b/www/seamonkey/patches/patch-mb @@ -1,20 +1,37 @@ -$NetBSD: patch-mb,v 1.13 2013/09/28 14:37:05 ryoon Exp $ +$NetBSD: patch-mb,v 1.14 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2013-09-16 18:27:02.000000000 +0000 +--- mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2014-03-19 01:42:18.000000000 +0000 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in -@@ -183,7 +183,7 @@ endif - # - # NetBSD/PPC - # --ifneq (,$(filter NetBSDmacppc NetBSDbebox NetBSDofppc NetBSDprep NetBSDamigappc,$(OS_ARCH)$(OS_TEST))) -+ifeq ($(OS_ARCH)$(OS_TEST),NetBSDpowerpc) - ASFILES := xptcinvoke_asm_ppc_netbsd.s xptcstubs_asm_ppc_netbsd.s - endif - -@@ -235,6 +235,13 @@ ifneq (,$(filter OpenBSDsparc64 FreeBSDs - ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s - endif +@@ -83,6 +83,39 @@ endif + # SPARC + ###################################################################### # ++# Linux/SPARC ++# ++ifeq ($(OS_ARCH),Linux) ++ifneq (,$(findstring sparc,$(OS_TEST))) ++ASFILES := xptcinvoke_asm_sparc_linux_GCC3.s xptcstubs_asm_sparc_solaris.s ++endif ++endif ++# ++# NetBSD/SPARC ++# ++ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc) ++ASFILES := xptcinvoke_asm_sparc_netbsd.s xptcstubs_asm_sparc_netbsd.s ++endif ++# ++# OpenBSD/SPARC ++# ++ifeq ($(OS_ARCH)$(OS_TEST),OpenBSDsparc) ++ASFILES := xptcinvoke_asm_sparc_openbsd.s xptcstubs_asm_sparc_openbsd.s ++endif ++# ++# OpenBSD/SPARC64 ++# ++ifneq (,$(filter OpenBSDsparc64 FreeBSDsparc64,$(OS_ARCH)$(OS_TEST))) ++ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s ++endif ++# +# NetBSD/SPARC64 +# +ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc64) diff --git a/www/seamonkey/patches/patch-mozilla_browser_app_nsBrowserApp.cpp b/www/seamonkey/patches/patch-mozilla_browser_app_nsBrowserApp.cpp new file mode 100644 index 00000000000..f7e1870fa0b --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_browser_app_nsBrowserApp.cpp @@ -0,0 +1,12 @@ +$NetBSD: patch-mozilla_browser_app_nsBrowserApp.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/browser/app/nsBrowserApp.cpp.orig 2014-03-19 01:41:43.000000000 +0000 ++++ mozilla/browser/app/nsBrowserApp.cpp +@@ -586,6 +586,7 @@ int main(int argc, char* argv[]) + TriggerQuirks(); + #endif + ++ setenv("MOZ_PLUGIN_PATH", "%%LOCALBASE%%/lib/browser_plugins/symlinks/gecko", 0); + int gotCounters; + #if defined(XP_UNIX) + struct rusage initialRUsage; diff --git a/www/seamonkey/patches/patch-mozilla_browser_installer_package-manifest.in b/www/seamonkey/patches/patch-mozilla_browser_installer_package-manifest.in index 0db09392b30..bb3905c98e2 100644 --- a/www/seamonkey/patches/patch-mozilla_browser_installer_package-manifest.in +++ b/www/seamonkey/patches/patch-mozilla_browser_installer_package-manifest.in @@ -1,9 +1,9 @@ -$NetBSD: patch-mozilla_browser_installer_package-manifest.in,v 1.1 2013/08/11 03:18:46 ryoon Exp $ +$NetBSD: patch-mozilla_browser_installer_package-manifest.in,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/browser/installer/package-manifest.in.orig 2013-08-04 03:05:17.000000000 +0000 +--- mozilla/browser/installer/package-manifest.in.orig 2014-03-19 01:41:45.000000000 +0000 +++ mozilla/browser/installer/package-manifest.in -@@ -693,7 +693,7 @@ - @BINPATH@/components/pippki.xpt +@@ -732,7 +732,7 @@ + #endif ; for Solaris SPARC -#ifdef SOLARIS diff --git a/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_common.css b/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_common.css new file mode 100644 index 00000000000..120d14f5a98 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_common.css @@ -0,0 +1,32 @@ +$NetBSD: patch-mozilla_browser_themes_shared_devtools_common.css,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/browser/themes/shared/devtools/common.css.orig 2014-03-19 01:41:45.000000000 +0000 ++++ mozilla/browser/themes/shared/devtools/common.css +@@ -11,13 +11,13 @@ + .devtools-monospace { + %ifdef XP_MACOSX + font-family: Menlo, monospace; +-%endif +-%ifdef XP_LINUX ++%elifdef XP_WIN ++ font-family: Consolas, monospace; ++%else + font-family: monospace; +- font-size: 80%; + %endif +-%ifdef XP_WIN +- font-family: Consolas, monospace; ++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT) ++ font-size: 80%; + %endif + } + +@@ -62,7 +62,7 @@ + background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%)); + border-radius: 3px; + overflow-x: hidden; +-%ifdef XP_LINUX ++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT) + max-height: 32rem; + %else + max-height: 40rem; diff --git a/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_highlighter.inc.css b/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_highlighter.inc.css new file mode 100644 index 00000000000..e47771f3c5b --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_browser_themes_shared_devtools_highlighter.inc.css @@ -0,0 +1,13 @@ +$NetBSD: patch-mozilla_browser_themes_shared_devtools_highlighter.inc.css,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/browser/themes/shared/devtools/highlighter.inc.css.orig 2014-03-19 01:41:45.000000000 +0000 ++++ mozilla/browser/themes/shared/devtools/highlighter.inc.css +@@ -54,7 +54,7 @@ html|*.highlighter-nodeinfobar-pseudo-cl + padding: 0; + width: 26px; + min-height: 26px; +-%ifndef XP_LINUX ++%if !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_QT) + background-color: transparent; + %endif + } diff --git a/www/seamonkey/patches/patch-mozilla_build_pgo_profileserver.py b/www/seamonkey/patches/patch-mozilla_build_pgo_profileserver.py new file mode 100644 index 00000000000..9aae9856922 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_build_pgo_profileserver.py @@ -0,0 +1,13 @@ +$NetBSD: patch-mozilla_build_pgo_profileserver.py,v 1.3 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/build/pgo/profileserver.py.orig 2014-03-19 01:41:46.000000000 +0000 ++++ mozilla/build/pgo/profileserver.py +@@ -59,7 +59,7 @@ if __name__ == '__main__': + env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog) + print "jarlog: %s" % env["MOZ_JAR_LOG_FILE"] + +- cmdargs = ["http://localhost:%d/index.html" % PORT] ++ cmdargs = ["http://127.0.0.1:%d/index.html" % PORT] + runner = FirefoxRunner(profile=profile, + binary=build.get_binary_path(where="staged-package"), + cmdargs=cmdargs, diff --git a/www/seamonkey/patches/patch-mozilla_config_Makefile.in b/www/seamonkey/patches/patch-mozilla_config_Makefile.in new file mode 100644 index 00000000000..1fdb64bac16 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_config_Makefile.in @@ -0,0 +1,16 @@ +$NetBSD: patch-mozilla_config_Makefile.in,v 1.3 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/config/Makefile.in.orig 2014-03-19 01:41:46.000000000 +0000 ++++ mozilla/config/Makefile.in +@@ -73,6 +73,11 @@ export:: $(export-preqs) + -DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \ + -DMOZ_NATIVE_LIBVPX=$(MOZ_NATIVE_LIBVPX) \ + -DMOZ_NATIVE_ICU=$(MOZ_NATIVE_ICU) \ ++ -DMOZ_NATIVE_GRAPHITE2=$(MOZ_NATIVE_GRAPHITE2) \ ++ -DMOZ_NATIVE_HARFBUZZ=$(MOZ_NATIVE_HARFBUZZ) \ ++ -DMOZ_NATIVE_OGG=$(MOZ_NATIVE_OGG) \ ++ -DMOZ_NATIVE_VORBIS=$(MOZ_NATIVE_VORBIS) \ ++ -DMOZ_NATIVE_OPUS=$(MOZ_NATIVE_OPUS) \ + $(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers + $(INSTALL) system_wrappers $(DIST) + diff --git a/www/seamonkey/patches/patch-mozilla_config_external_moz.build b/www/seamonkey/patches/patch-mozilla_config_external_moz.build new file mode 100644 index 00000000000..0a4f7e93115 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_config_external_moz.build @@ -0,0 +1,31 @@ +$NetBSD: patch-mozilla_config_external_moz.build,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/config/external/moz.build.orig 2014-03-19 01:41:46.000000000 +0000 ++++ mozilla/config/external/moz.build +@@ -15,13 +15,13 @@ if CONFIG['MOZ_UPDATER']: + if not CONFIG['MOZ_NATIVE_BZ2']: + external_dirs += ['modules/libbz2'] + +-if CONFIG['MOZ_VORBIS']: ++if CONFIG['MOZ_VORBIS'] and not CONFIG['MOZ_NATIVE_VORBIS']: + external_dirs += ['media/libvorbis'] + + if CONFIG['MOZ_TREMOR']: + external_dirs += ['media/libtremor'] + +-if CONFIG['MOZ_OPUS']: ++if CONFIG['MOZ_OPUS'] and not CONFIG['MOZ_NATIVE_OPUS']: + external_dirs += ['media/libopus'] + + if CONFIG['MOZ_WEBM']: +@@ -31,7 +31,9 @@ if CONFIG['MOZ_VP8'] and not CONFIG['MOZ + external_dirs += ['media/libvpx'] + + if CONFIG['MOZ_OGG']: +- external_dirs += ['media/libogg', 'media/libtheora'] ++ if not CONFIG['MOZ_NATIVE_OGG']: ++ external_dirs += ['media/libogg'] ++ external_dirs += ['media/libtheora'] + + if not CONFIG['MOZ_NATIVE_PNG']: + external_dirs += ['media/libpng'] diff --git a/www/seamonkey/patches/patch-mozilla_config_system-headers b/www/seamonkey/patches/patch-mozilla_config_system-headers index 15af8c196b1..60445827a8a 100644 --- a/www/seamonkey/patches/patch-mozilla_config_system-headers +++ b/www/seamonkey/patches/patch-mozilla_config_system-headers @@ -1,9 +1,33 @@ -$NetBSD: patch-mozilla_config_system-headers,v 1.9 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_config_system-headers,v 1.10 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/config/system-headers.orig 2013-12-11 04:28:28.000000000 +0000 +--- mozilla/config/system-headers.orig 2014-03-19 01:41:46.000000000 +0000 +++ mozilla/config/system-headers -@@ -1144,3 +1144,4 @@ unicode/unum.h +@@ -1144,4 +1144,28 @@ unicode/unum.h unicode/ustring.h unicode/utypes.h #endif -+libutil.h ++cairo-qt.h ++#if MOZ_NATIVE_GRAPHITE2==1 ++unwind.h ++graphite2/Font.h ++graphite2/Segment.h ++#endif ++#if MOZ_NATIVE_HARFBUZZ==1 ++harfbuzz/hb-ot.h ++harfbuzz/hb.h ++#endif ++#if MOZ_NATIVE_OGG==1 ++ogg/ogg.h ++ogg/os_types.h ++#endif ++#if MOZ_NATIVE_VORBIS==1 ++vorbis/codec.h ++vorbis/vorbisenc.h ++#endif ++#if MOZ_NATIVE_OPUS==1 ++opus.h ++opus_multistream.h ++opus/opus.h ++opus/opus_multistream.h ++#endif + libutil.h diff --git a/www/seamonkey/patches/patch-mozilla_content_base_src_Makefile.in b/www/seamonkey/patches/patch-mozilla_content_base_src_Makefile.in new file mode 100644 index 00000000000..16da4473320 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_base_src_Makefile.in @@ -0,0 +1,15 @@ +$NetBSD: patch-mozilla_content_base_src_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/base/src/Makefile.in.orig 2014-03-19 01:41:46.000000000 +0000 ++++ mozilla/content/base/src/Makefile.in +@@ -5,6 +5,10 @@ + + include $(topsrcdir)/config/rules.mk + ++ifdef MOZ_NATIVE_HARFBUZZ ++nsContentUtils.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + # gcc requires -msse2 for this file since it uses SSE2 intrinsics. (See bug + # 585538 comment 12.) + ifneq (,$(INTEL_ARCHITECTURE)) diff --git a/www/seamonkey/patches/patch-mozilla_content_media_Makefile.in b/www/seamonkey/patches/patch-mozilla_content_media_Makefile.in new file mode 100644 index 00000000000..f2a9a317966 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_Makefile.in @@ -0,0 +1,21 @@ +$NetBSD: patch-mozilla_content_media_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/Makefile.in.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/Makefile.in +@@ -7,4 +7,16 @@ include $(topsrcdir)/config/rules.mk + CFLAGS += $(GSTREAMER_CFLAGS) + CXXFLAGS += $(GSTREAMER_CFLAGS) + ++ifdef MOZ_NATIVE_OGG ++CXXFLAGS += $(MOZ_OGG_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_VORBIS ++CXXFLAGS += $(MOZ_VORBIS_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_OPUS ++CXXFLAGS += $(MOZ_OPUS_CFLAGS) ++endif ++ + AudioNodeEngineNEON.$(OBJ_SUFFIX): CXXFLAGS += -mfpu=neon diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.cpp b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.cpp new file mode 100644 index 00000000000..4838fc9045f --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.cpp @@ -0,0 +1,203 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerAllocator.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerAllocator.cpp.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerAllocator.cpp +@@ -0,0 +1,198 @@ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "GStreamerAllocator.h" ++ ++#include <gst/video/video.h> ++#include <gst/video/gstvideometa.h> ++ ++#include "GStreamerLoader.h" ++ ++using namespace mozilla::layers; ++ ++namespace mozilla { ++ ++typedef struct ++{ ++ GstAllocator parent; ++ GStreamerReader *reader; ++} MozGfxMemoryAllocator; ++ ++typedef struct ++{ ++ GstAllocatorClass parent; ++} MozGfxMemoryAllocatorClass; ++ ++typedef struct ++{ ++ GstMemory memory; ++ PlanarYCbCrImage* image; ++ guint8* data; ++} MozGfxMemory; ++ ++typedef struct ++{ ++ GstMeta meta; ++} MozGfxMeta; ++ ++typedef struct ++{ ++ GstVideoBufferPoolClass parent_class; ++} MozGfxBufferPoolClass; ++ ++typedef struct ++{ ++ GstVideoBufferPool pool; ++} MozGfxBufferPool; ++ ++G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR); ++G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL); ++ ++void ++moz_gfx_memory_reset(MozGfxMemory *mem) ++{ ++ if (mem->image) ++ mem->image->Release(); ++ ++ ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer(); ++ ImageFormat format = PLANAR_YCBCR; ++ mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); ++ mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size); ++} ++ ++static GstMemory* ++moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize, ++ GstAllocationParams* aParams) ++{ ++ MozGfxMemory* mem = g_slice_new (MozGfxMemory); ++ gsize maxsize = aSize + aParams->prefix + aParams->padding; ++ gst_memory_init(GST_MEMORY_CAST (mem), ++ (GstMemoryFlags)aParams->flags, ++ aAllocator, NULL, maxsize, aParams->align, ++ aParams->prefix, aSize); ++ mem->image = NULL; ++ moz_gfx_memory_reset(mem); ++ ++ return (GstMemory *) mem; ++} ++ ++static void ++moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem) ++{ ++ MozGfxMemory *mem = (MozGfxMemory *) gmem; ++ ++ if (mem->memory.parent) ++ goto sub_mem; ++ ++ if (mem->image) ++ mem->image->Release(); ++ ++sub_mem: ++ g_slice_free (MozGfxMemory, mem); ++} ++ ++static gpointer ++moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags) ++{ ++ // check that the allocation didn't fail ++ if (mem->data == nullptr) ++ return nullptr; ++ ++ return mem->data + mem->memory.offset; ++} ++ ++static gboolean ++moz_gfx_memory_unmap (MozGfxMemory * mem) ++{ ++ return TRUE; ++} ++ ++static MozGfxMemory * ++moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) ++{ ++ MozGfxMemory *sub; ++ GstMemory *parent; ++ ++ /* find the real parent */ ++ if ((parent = mem->memory.parent) == NULL) ++ parent = (GstMemory *) mem; ++ ++ if (size == (gsize) -1) ++ size = mem->memory.size - offset; ++ ++ /* the shared memory is always readonly */ ++ sub = g_slice_new (MozGfxMemory); ++ ++ gst_memory_init (GST_MEMORY_CAST (sub), ++ (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), ++ mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, ++ mem->memory.offset + offset, size); ++ ++ sub->image = mem->image; ++ sub->data = mem->data; ++ ++ return sub; ++} ++ ++static void ++moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass) ++{ ++ GstAllocatorClass *allocator_class; ++ ++ allocator_class = (GstAllocatorClass *) klass; ++ ++ allocator_class->alloc = moz_gfx_memory_allocator_alloc; ++ allocator_class->free = moz_gfx_memory_allocator_free; ++} ++ ++static void ++moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator) ++{ ++ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); ++ ++ alloc->mem_type = "moz-gfx-image"; ++ alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map; ++ alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap; ++ alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share; ++ /* fallback copy and is_span */ ++} ++ ++void ++moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader) ++{ ++ MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator; ++ allocator->reader = aReader; ++} ++ ++nsRefPtr<PlanarYCbCrImage> ++moz_gfx_memory_get_image(GstMemory *aMemory) ++{ ++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image"); ++ ++ return ((MozGfxMemory *) aMemory)->image; ++} ++ ++void ++moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) ++{ ++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); ++ ++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); ++ moz_gfx_memory_reset((MozGfxMemory *) mem); ++ GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); ++} ++ ++static void ++moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass) ++{ ++ GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass; ++ pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer; ++} ++ ++static void ++moz_gfx_buffer_pool_init (MozGfxBufferPool * pool) ++{ ++} ++ ++} // namespace mozilla diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.h b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.h new file mode 100644 index 00000000000..eb9af39d70f --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerAllocator.h @@ -0,0 +1,30 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerAllocator.h,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerAllocator.h.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerAllocator.h +@@ -0,0 +1,25 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this file, ++ * You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#if !defined(GStreamerAllocator_h_) ++#define GStreamerAllocator_h_ ++ ++#include "GStreamerReader.h" ++ ++#define GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR (moz_gfx_memory_allocator_get_type()) ++#define GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR)) ++#define GST_TYPE_MOZ_GFX_BUFFER_POOL (moz_gfx_buffer_pool_get_type()) ++#define GST_IS_MOZ_GFX_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_BUFFER_POOL)) ++ ++namespace mozilla { ++ ++GType moz_gfx_memory_allocator_get_type(); ++void moz_gfx_memory_allocator_set_reader(GstAllocator *aAllocator, GStreamerReader* aReader); ++nsRefPtr<layers::PlanarYCbCrImage> moz_gfx_memory_get_image(GstMemory *aMemory); ++ ++GType moz_gfx_buffer_pool_get_type(); ++ ++} // namespace mozilla ++ ++#endif diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFormatHelper.cpp b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFormatHelper.cpp new file mode 100644 index 00000000000..2b3d7e06052 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFormatHelper.cpp @@ -0,0 +1,29 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerFormatHelper.cpp,v 1.3 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerFormatHelper.cpp.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerFormatHelper.cpp +@@ -294,12 +294,23 @@ bool GStreamerFormatHelper::CanHandleCod + GList* GStreamerFormatHelper::GetFactories() { + NS_ASSERTION(sLoadOK, "GStreamer library not linked"); + +- uint32_t cookie = gst_default_registry_get_feature_list_cookie (); ++#if GST_VERSION_MAJOR >= 1 ++ uint32_t cookie = gst_registry_get_feature_list_cookie(gst_registry_get()); ++#else ++ uint32_t cookie = gst_default_registry_get_feature_list_cookie(); ++#endif + if (cookie != mCookie) { + g_list_free(mFactories); ++#if GST_VERSION_MAJOR >= 1 ++ mFactories = ++ gst_registry_feature_filter(gst_registry_get(), ++ (GstPluginFeatureFilter)FactoryFilter, ++ false, nullptr); ++#else + mFactories = + gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter, + false, nullptr); ++#endif + mCookie = cookie; + } + diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFunctionList.h b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFunctionList.h new file mode 100644 index 00000000000..ae6420e65e5 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerFunctionList.h @@ -0,0 +1,168 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerFunctionList.h,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerFunctionList.h.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerFunctionList.h +@@ -9,7 +9,6 @@ + * List of symbol names we need to dlsym from the gstreamer library. + */ + GST_FUNC(LIBGSTAPP, gst_app_sink_get_type) +-GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) + GST_FUNC(LIBGSTAPP, gst_app_sink_set_callbacks) + GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream) + GST_FUNC(LIBGSTAPP, gst_app_src_get_size) +@@ -22,10 +21,8 @@ GST_FUNC(LIBGSTAPP, gst_app_src_set_stre + GST_FUNC(LIBGSTREAMER, gst_bin_get_by_name) + GST_FUNC(LIBGSTREAMER, gst_bin_get_type) + GST_FUNC(LIBGSTREAMER, gst_bin_iterate_recurse) +-GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) + GST_FUNC(LIBGSTREAMER, gst_buffer_get_type) + GST_FUNC(LIBGSTREAMER, gst_buffer_new) +-GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) + GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler) + GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered) + GST_FUNC(LIBGSTREAMER, gst_caps_append) +@@ -37,47 +34,37 @@ GST_FUNC(LIBGSTREAMER, gst_caps_new_any) + GST_FUNC(LIBGSTREAMER, gst_caps_new_empty) + GST_FUNC(LIBGSTREAMER, gst_caps_new_full) + GST_FUNC(LIBGSTREAMER, gst_caps_new_simple) +-GST_FUNC(LIBGSTREAMER, gst_caps_unref) +-GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) ++GST_FUNC(LIBGSTREAMER, gst_caps_set_simple) + GST_FUNC(LIBGSTREAMER, gst_element_factory_get_static_pad_templates) + GST_FUNC(LIBGSTREAMER, gst_element_factory_get_type) + GST_FUNC(LIBGSTREAMER, gst_element_factory_make) + GST_FUNC(LIBGSTREAMER, gst_element_get_factory) +-GST_FUNC(LIBGSTREAMER, gst_element_get_pad) ++GST_FUNC(LIBGSTREAMER, gst_element_get_static_pad) + GST_FUNC(LIBGSTREAMER, gst_element_get_type) + GST_FUNC(LIBGSTREAMER, gst_element_query_convert) + GST_FUNC(LIBGSTREAMER, gst_element_query_duration) + GST_FUNC(LIBGSTREAMER, gst_element_seek_simple) + GST_FUNC(LIBGSTREAMER, gst_element_set_state) +-GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) + GST_FUNC(LIBGSTREAMER, gst_flow_get_name) + GST_FUNC(LIBGSTREAMER, gst_init) + GST_FUNC(LIBGSTREAMER, gst_init_check) + GST_FUNC(LIBGSTREAMER, gst_iterator_next) + GST_FUNC(LIBGSTREAMER, gst_message_parse_error) + GST_FUNC(LIBGSTREAMER, gst_message_type_get_name) +-GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) +-GST_FUNC(LIBGSTREAMER, gst_mini_object_new) + GST_FUNC(LIBGSTREAMER, gst_mini_object_ref) + GST_FUNC(LIBGSTREAMER, gst_mini_object_unref) + GST_FUNC(LIBGSTREAMER, gst_object_get_name) + GST_FUNC(LIBGSTREAMER, gst_object_get_parent) + GST_FUNC(LIBGSTREAMER, gst_object_unref) +-GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) +-GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) + GST_FUNC(LIBGSTREAMER, gst_pad_get_element_private) +-GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) +-GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) + GST_FUNC(LIBGSTREAMER, gst_pad_set_element_private) + GST_FUNC(LIBGSTREAMER, gst_parse_bin_from_description) + GST_FUNC(LIBGSTREAMER, gst_pipeline_get_bus) + GST_FUNC(LIBGSTREAMER, gst_pipeline_get_type) + GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_rank) + GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter) +-GST_FUNC(LIBGSTREAMER, gst_registry_get_default) + GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie) + GST_FUNC(LIBGSTREAMER, gst_segment_init) +-GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) + GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time) + GST_FUNC(LIBGSTREAMER, gst_static_caps_get) + GST_FUNC(LIBGSTREAMER, gst_structure_copy) +@@ -86,11 +73,82 @@ GST_FUNC(LIBGSTREAMER, gst_structure_get + GST_FUNC(LIBGSTREAMER, gst_structure_get_value) + GST_FUNC(LIBGSTREAMER, gst_structure_new) + GST_FUNC(LIBGSTREAMER, gst_util_uint64_scale) ++ ++#if GST_VERSION_MAJOR == 0 ++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) ++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) ++GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) ++GST_FUNC(LIBGSTREAMER, gst_caps_unref) ++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) ++GST_FUNC(LIBGSTREAMER, gst_element_get_pad) ++GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) ++GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) ++GST_FUNC(LIBGSTREAMER, gst_mini_object_new) ++GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) ++GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) ++GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) ++GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) ++GST_FUNC(LIBGSTREAMER, gst_registry_get_default) ++GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_height) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_offset) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_width) ++GST_FUNC(LIBGSTVIDEO, gst_video_format_get_pixel_stride) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_row_stride) + GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps) ++#else ++ ++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_sample) ++GST_FUNC(LIBGSTREAMER, _gst_caps_any) ++GST_FUNC(LIBGSTREAMER, gst_allocator_get_type) ++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_into) ++GST_FUNC(LIBGSTREAMER, gst_buffer_extract) ++GST_FUNC(LIBGSTREAMER, gst_buffer_get_meta) ++GST_FUNC(LIBGSTREAMER, gst_buffer_get_size) ++GST_FUNC(LIBGSTREAMER, gst_buffer_map) ++GST_FUNC(LIBGSTREAMER, gst_buffer_new_allocate) ++GST_FUNC(LIBGSTREAMER, gst_buffer_n_memory) ++GST_FUNC(LIBGSTREAMER, gst_buffer_peek_memory) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_acquire_buffer) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_allocator) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_params) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_config) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_type) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_is_active) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_active) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_config) ++GST_FUNC(LIBGSTREAMER, gst_buffer_set_size) ++GST_FUNC(LIBGSTREAMER, gst_buffer_unmap) ++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_metadata) ++GST_FUNC(LIBGSTREAMER, gst_event_parse_segment) ++GST_FUNC(LIBGSTREAMER, gst_memory_init) ++GST_FUNC(LIBGSTREAMER, gst_memory_map) ++GST_FUNC(LIBGSTREAMER, gst_memory_unmap) ++GST_FUNC(LIBGSTREAMER, gst_object_get_type) ++GST_FUNC(LIBGSTREAMER, gst_pad_add_probe) ++GST_FUNC(LIBGSTREAMER, gst_pad_get_current_caps) ++GST_FUNC(LIBGSTREAMER, gst_pad_probe_info_get_query) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_meta) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_param) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_pool) ++GST_FUNC(LIBGSTREAMER, gst_query_parse_allocation) ++GST_FUNC(LIBGSTREAMER, gst_registry_get) ++GST_FUNC(LIBGSTREAMER, gst_sample_get_buffer) ++GST_FUNC(LIBGSTREAMER, gst_segment_copy_into) ++GST_FUNC(LIBGSTREAMER, gst_structure_free) ++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_config_get_video_alignment) ++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_has_option) ++GST_FUNC(LIBGSTVIDEO, gst_video_buffer_pool_get_type) ++GST_FUNC(LIBGSTVIDEO, gst_video_frame_map) ++GST_FUNC(LIBGSTVIDEO, gst_video_frame_unmap) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_align) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_from_caps) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_init) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_api_get_type) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_map) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_unmap) ++ ++#endif + + /* + * Functions that have been defined in the header file. We replace them so that +@@ -100,6 +158,11 @@ GST_FUNC(LIBGSTVIDEO, gst_video_format_p + REPLACE_FUNC(gst_buffer_ref); + REPLACE_FUNC(gst_buffer_unref); + REPLACE_FUNC(gst_message_unref); ++ ++#if GST_VERSION_MAJOR == 1 ++REPLACE_FUNC(gst_caps_unref); ++REPLACE_FUNC(gst_sample_unref); ++#endif + #endif + + #endif // !defined(__APPLE__) diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.cpp b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.cpp new file mode 100644 index 00000000000..feef5eb8f03 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.cpp @@ -0,0 +1,97 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerLoader.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerLoader.cpp.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerLoader.cpp +@@ -6,13 +6,21 @@ + #include <dlfcn.h> + #include <stdio.h> + +-#include "GStreamerLoader.h" ++#include "nsDebug.h" + #include "mozilla/NullPtr.h" + ++#include "GStreamerLoader.h" ++ + #define LIBGSTREAMER 0 + #define LIBGSTAPP 1 + #define LIBGSTVIDEO 2 + ++#ifdef __OpenBSD__ ++#define LIB_GST_SUFFIX ".so" ++#else ++#define LIB_GST_SUFFIX ".so.0" ++#endif ++ + namespace mozilla { + + /* +@@ -32,6 +40,11 @@ namespace mozilla { + GstBuffer * gst_buffer_ref_impl(GstBuffer *buf); + void gst_buffer_unref_impl(GstBuffer *buf); + void gst_message_unref_impl(GstMessage *msg); ++void gst_caps_unref_impl(GstCaps *caps); ++ ++#if GST_VERSION_MAJOR == 1 ++void gst_sample_unref_impl(GstSample *sample); ++#endif + + bool + load_gstreamer() +@@ -58,32 +71,25 @@ load_gstreamer() + if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) { + gstreamerLib = RTLD_DEFAULT; + } else { +-#ifdef __OpenBSD__ +- gstreamerLib = dlopen("libgstreamer-0.10.so", RTLD_NOW | RTLD_LOCAL); +-#else +- gstreamerLib = dlopen("libgstreamer-0.10.so.0", RTLD_NOW | RTLD_LOCAL); +-#endif ++ gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL); + } + +- void *handles[] = { ++ void *handles[3] = { + gstreamerLib, +-#ifdef __OpenBSD__ +- dlopen("libgstapp-0.10.so", RTLD_NOW | RTLD_LOCAL), +- dlopen("libgstvideo-0.10.so", RTLD_NOW | RTLD_LOCAL) +-#else +- dlopen("libgstapp-0.10.so.0", RTLD_NOW | RTLD_LOCAL), +- dlopen("libgstvideo-0.10.so.0", RTLD_NOW | RTLD_LOCAL) +-#endif ++ dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL), ++ dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL) + }; + + for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) { + if (!handles[i]) { ++ NS_WARNING("Couldn't link gstreamer libraries"); + goto fail; + } + } + + #define GST_FUNC(lib, symbol) \ + if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \ ++ NS_WARNING("Couldn't link symbol " #symbol); \ + goto fail; \ + } + #define REPLACE_FUNC(symbol) symbol = symbol##_impl; +@@ -123,4 +129,18 @@ gst_message_unref_impl(GstMessage *msg) + gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg)); + } + ++#if GST_VERSION_MAJOR == 1 ++void ++gst_sample_unref_impl(GstSample *sample) ++{ ++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample)); ++} ++#endif ++ ++void ++gst_caps_unref_impl(GstCaps *caps) ++{ ++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps)); ++} ++ + } diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.h b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.h new file mode 100644 index 00000000000..4878a3d97aa --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerLoader.h @@ -0,0 +1,24 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerLoader.h,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerLoader.h.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerLoader.h +@@ -22,6 +22,11 @@ + #include <gst/video/video.h> + #pragma GCC diagnostic pop + ++#if GST_VERSION_MAJOR == 1 ++#include <gst/video/gstvideometa.h> ++#include <gst/video/gstvideopool.h> ++#endif ++ + namespace mozilla { + + /* +@@ -42,4 +47,7 @@ bool load_gstreamer(); + + } + ++#undef GST_CAPS_ANY ++#define GST_CAPS_ANY (*_gst_caps_any) ++ + #endif // GStreamerLoader_h_ diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader-0.10.cpp b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader-0.10.cpp new file mode 100644 index 00000000000..a3341e7e605 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader-0.10.cpp @@ -0,0 +1,208 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerReader-0.10.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerReader-0.10.cpp.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerReader-0.10.cpp +@@ -0,0 +1,203 @@ ++#include "nsError.h" ++#include "MediaDecoderStateMachine.h" ++#include "AbstractMediaDecoder.h" ++#include "MediaResource.h" ++#include "GStreamerReader.h" ++#include "GStreamerMozVideoBuffer.h" ++#include "GStreamerFormatHelper.h" ++#include "VideoUtils.h" ++#include "mozilla/dom/TimeRanges.h" ++#include "mozilla/Preferences.h" ++ ++using namespace mozilla; ++using mozilla::layers::PlanarYCbCrImage; ++using mozilla::layers::ImageContainer; ++ ++GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); ++ return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf); ++} ++ ++GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf) ++{ ++ nsRefPtr<PlanarYCbCrImage> image; ++ return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image); ++} ++ ++GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf, ++ nsRefPtr<PlanarYCbCrImage>& aImage) ++{ ++ /* allocate an image using the container */ ++ ImageContainer* container = mDecoder->GetImageContainer(); ++ if (!container) { ++ // We don't have an ImageContainer. We probably belong to an <audio> ++ // element. ++ return GST_FLOW_NOT_SUPPORTED; ++ } ++ ImageFormat format = PLANAR_YCBCR; ++ PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); ++ nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img); ++ ++ /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */ ++ GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new()); ++ GST_BUFFER_SIZE(buf) = aSize; ++ /* allocate the actual YUV buffer */ ++ GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize); ++ ++ aImage = image; ++ ++ /* create a GstMozVideoBufferData to hold the image */ ++ GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image); ++ ++ /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */ ++ gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata); ++ ++ *aBuf = buf; ++ return GST_FLOW_OK; ++} ++ ++gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent) ++{ ++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); ++ switch(GST_EVENT_TYPE(aEvent)) { ++ case GST_EVENT_NEWSEGMENT: ++ { ++ gboolean update; ++ gdouble rate; ++ GstFormat format; ++ gint64 start, stop, position; ++ GstSegment* segment; ++ ++ /* Store the segments so we can convert timestamps to stream time, which ++ * is what the upper layers sync on. ++ */ ++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); ++ gst_event_parse_new_segment(aEvent, &update, &rate, &format, ++ &start, &stop, &position); ++ if (parent == GST_ELEMENT(mVideoAppSink)) ++ segment = &mVideoSegment; ++ else ++ segment = &mAudioSegment; ++ gst_segment_set_newsegment(segment, update, rate, format, ++ start, stop, position); ++ break; ++ } ++ case GST_EVENT_FLUSH_STOP: ++ /* Reset on seeks */ ++ ResetDecode(); ++ break; ++ default: ++ break; ++ } ++ gst_object_unref(parent); ++ ++ return TRUE; ++} ++ ++gboolean GStreamerReader::EventProbeCb(GstPad* aPad, ++ GstEvent* aEvent, ++ gpointer aUserData) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData); ++ return reader->EventProbe(aPad, aEvent); ++} ++ ++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer) ++{ ++ if (!GST_IS_MOZ_VIDEO_BUFFER (aBuffer)) ++ return nullptr; ++ ++ nsRefPtr<PlanarYCbCrImage> image; ++ GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>(gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(aBuffer))); ++ image = bufferdata->mImage; ++ ++ PlanarYCbCrImage::Data data; ++ data.mPicX = data.mPicY = 0; ++ data.mPicSize = nsIntSize(mPicture.width, mPicture.height); ++ data.mStereoMode = STEREO_MODE_MONO; ++ ++ data.mYChannel = GST_BUFFER_DATA(aBuffer); ++ data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width); ++ data.mYSize = nsIntSize(data.mYStride, ++ gst_video_format_get_component_height(mFormat, 0, mPicture.height)); ++ data.mYSkip = 0; ++ data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width); ++ data.mCbCrSize = nsIntSize(data.mCbCrStride, ++ gst_video_format_get_component_height(mFormat, 1, mPicture.height)); ++ data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1, ++ mPicture.width, mPicture.height); ++ data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2, ++ mPicture.width, mPicture.height); ++ data.mCbSkip = 0; ++ data.mCrSkip = 0; ++ ++ image->SetDataNoCopy(data); ++ ++ return image; ++} ++ ++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer, ++ GstBuffer** aOutBuffer, ++ nsRefPtr<PlanarYCbCrImage> &aImage) ++{ ++ AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(aBuffer), ++ GST_BUFFER_SIZE(aBuffer), nullptr, aOutBuffer, aImage); ++ ++ gst_buffer_copy_metadata(*aOutBuffer, aBuffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL); ++ memcpy(GST_BUFFER_DATA(*aOutBuffer), GST_BUFFER_DATA(aBuffer), GST_BUFFER_SIZE(*aOutBuffer)); ++ ++ aImage = GetImageFromBuffer(*aOutBuffer); ++} ++ ++GstCaps* GStreamerReader::BuildAudioSinkCaps() ++{ ++ GstCaps* caps; ++#ifdef IS_LITTLE_ENDIAN ++ int endianness = 1234; ++#else ++ int endianness = 4321; ++#endif ++ gint width; ++#ifdef MOZ_SAMPLE_TYPE_FLOAT32 ++ caps = gst_caps_from_string("audio/x-raw-float, channels={1,2}"); ++ width = 32; ++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */ ++ caps = gst_caps_from_string("audio/x-raw-int, channels={1,2}"); ++ width = 16; ++#endif ++ gst_caps_set_simple(caps, ++ "width", G_TYPE_INT, width, ++ "endianness", G_TYPE_INT, endianness, ++ NULL); ++ ++ return caps; ++} ++ ++void GStreamerReader::InstallPadCallbacks() ++{ ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ gst_pad_add_event_probe(sinkpad, ++ G_CALLBACK(&GStreamerReader::EventProbeCb), this); ++ ++ gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb); ++ gst_pad_set_element_private(sinkpad, this); ++ gst_object_unref(sinkpad); ++ ++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ gst_pad_add_event_probe(sinkpad, ++ G_CALLBACK(&GStreamerReader::EventProbeCb), this); ++ gst_object_unref(sinkpad); ++} diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.cpp b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.cpp new file mode 100644 index 00000000000..81057161d46 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.cpp @@ -0,0 +1,969 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerReader.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerReader.cpp.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerReader.cpp +@@ -10,8 +10,10 @@ + #include "AbstractMediaDecoder.h" + #include "MediaResource.h" + #include "GStreamerReader.h" ++#if GST_VERSION_MAJOR >= 1 ++#include "GStreamerAllocator.h" ++#endif + #include "GStreamerFormatHelper.h" +-#include "GStreamerMozVideoBuffer.h" + #include "VideoUtils.h" + #include "mozilla/dom/TimeRanges.h" + #include "mozilla/Preferences.h" +@@ -33,14 +35,16 @@ extern PRLogModuleInfo* gMediaDecoderLog + #define LOG(type, msg, ...) + #endif + +-extern bool +-IsYV12Format(const VideoData::YCbCrBuffer::Plane& aYPlane, +- const VideoData::YCbCrBuffer::Plane& aCbPlane, +- const VideoData::YCbCrBuffer::Plane& aCrPlane); +- ++#if DEBUG + static const unsigned int MAX_CHANNELS = 4; +-// Let the demuxer work in pull mode for short files +-static const int SHORT_FILE_SIZE = 1024 * 1024; ++#endif ++// Let the demuxer work in pull mode for short files. This used to be a micro ++// optimization to have more accurate durations for ogg files in mochitests. ++// Since as of today we aren't using gstreamer to demux ogg, and having demuxers ++// work in pull mode over http makes them slower (since they really assume ++// near-zero latency in pull mode) set the constant to 0 for now, which ++// effectively disables it. ++static const int SHORT_FILE_SIZE = 0; + // The default resource->Read() size when working in push mode + static const int DEFAULT_SOURCE_READ_SIZE = 50 * 1024; + +@@ -62,6 +66,10 @@ GStreamerReader::GStreamerReader(Abstrac + : MediaDecoderReader(aDecoder), + mMP3FrameParser(aDecoder->GetResource()->GetLength()), + mUseParserDuration(false), ++#if GST_VERSION_MAJOR >= 1 ++ mAllocator(nullptr), ++ mBufferPool(nullptr), ++#endif + mPlayBin(nullptr), + mBus(nullptr), + mSource(nullptr), +@@ -74,6 +82,9 @@ GStreamerReader::GStreamerReader(Abstrac + mAudioSinkBufferCount(0), + mGstThreadsMonitor("media.gst.threads"), + mReachedEos(false), ++#if GST_VERSION_MAJOR >= 1 ++ mConfigureAlignment(true), ++#endif + fpsNum(0), + fpsDen(0) + { +@@ -85,8 +96,12 @@ GStreamerReader::GStreamerReader(Abstrac + + mSinkCallbacks.eos = GStreamerReader::EosCb; + mSinkCallbacks.new_preroll = GStreamerReader::NewPrerollCb; ++#if GST_VERSION_MAJOR >= 1 ++ mSinkCallbacks.new_sample = GStreamerReader::NewBufferCb; ++#else + mSinkCallbacks.new_buffer = GStreamerReader::NewBufferCb; + mSinkCallbacks.new_buffer_list = nullptr; ++#endif + + gst_segment_init(&mVideoSegment, GST_FORMAT_UNDEFINED); + gst_segment_init(&mAudioSegment, GST_FORMAT_UNDEFINED); +@@ -110,65 +125,59 @@ GStreamerReader::~GStreamerReader() + mAudioAppSink = nullptr; + gst_object_unref(mBus); + mBus = nullptr; ++#if GST_VERSION_MAJOR >= 1 ++ g_object_unref(mAllocator); ++ g_object_unref(mBufferPool); ++#endif + } + } + + nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor) + { +- GError* error = nullptr; +- if (!gst_init_check(0, 0, &error)) { +- LOG(PR_LOG_ERROR, "gst initialization failed: %s", error->message); +- g_error_free(error); +- return NS_ERROR_FAILURE; +- } ++ GStreamerFormatHelper::Instance(); ++ ++#if GST_VERSION_MAJOR >= 1 ++ mAllocator = static_cast<GstAllocator*>(g_object_new(GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR, nullptr)); ++ moz_gfx_memory_allocator_set_reader(mAllocator, this); ++ ++ mBufferPool = static_cast<GstBufferPool*>(g_object_new(GST_TYPE_MOZ_GFX_BUFFER_POOL, nullptr)); ++#endif + ++#if GST_VERSION_MAJOR >= 1 ++ mPlayBin = gst_element_factory_make("playbin", nullptr); ++#else + mPlayBin = gst_element_factory_make("playbin2", nullptr); ++#endif + if (!mPlayBin) { +- LOG(PR_LOG_ERROR, "couldn't create playbin2"); ++ LOG(PR_LOG_ERROR, "couldn't create playbin"); + return NS_ERROR_FAILURE; + } + g_object_set(mPlayBin, "buffer-size", 0, nullptr); + mBus = gst_pipeline_get_bus(GST_PIPELINE(mPlayBin)); + + mVideoSink = gst_parse_bin_from_description("capsfilter name=filter ! " +- "appsink name=videosink sync=true max-buffers=1 " ++ "appsink name=videosink sync=false max-buffers=1 " ++#if GST_VERSION_MAJOR >= 1 ++ "caps=video/x-raw,format=I420" ++#else + "caps=video/x-raw-yuv,format=(fourcc)I420" ++#endif + , TRUE, nullptr); + mVideoAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mVideoSink), + "videosink")); +- gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks, +- (gpointer) this, nullptr); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink"); +- gst_pad_add_event_probe(sinkpad, +- G_CALLBACK(&GStreamerReader::EventProbeCb), this); +- gst_object_unref(sinkpad); +- gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb); +- gst_pad_set_element_private(sinkpad, this); +- + mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! " +-#ifdef MOZ_SAMPLE_TYPE_FLOAT32 +- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-float," +-#ifdef IS_LITTLE_ENDIAN +- "channels={1,2},width=32,endianness=1234", TRUE, nullptr); +-#else +- "channels={1,2},width=32,endianness=4321", TRUE, nullptr); +-#endif +-#else +- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-int," +-#ifdef IS_LITTLE_ENDIAN +- "channels={1,2},width=16,endianness=1234", TRUE, nullptr); +-#else +- "channels={1,2},width=16,endianness=4321", TRUE, nullptr); +-#endif +-#endif ++ "appsink name=audiosink sync=false max-buffers=1", TRUE, nullptr); + mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink), + "audiosink")); ++ GstCaps* caps = BuildAudioSinkCaps(); ++ g_object_set(mAudioAppSink, "caps", caps, nullptr); ++ gst_caps_unref(caps); ++ ++ gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks, ++ (gpointer) this, nullptr); + gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks, + (gpointer) this, nullptr); +- sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink"); +- gst_pad_add_event_probe(sinkpad, +- G_CALLBACK(&GStreamerReader::EventProbeCb), this); +- gst_object_unref(sinkpad); ++ InstallPadCallbacks(); + + g_object_set(mPlayBin, "uri", "appsrc://", + "video-sink", mVideoSink, +@@ -331,7 +340,7 @@ nsresult GStreamerReader::ReadMetadata(M + /* Little trick: set the target caps to "skip" so that playbin2 fails to + * find a decoder for the stream we want to skip. + */ +- GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr); ++ GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr, nullptr); + g_object_set(filter, "caps", filterCaps, nullptr); + gst_caps_unref(filterCaps); + gst_object_unref(filter); +@@ -358,6 +367,7 @@ nsresult GStreamerReader::ReadMetadata(M + gst_message_unref(message); + ret = NS_ERROR_FAILURE; + } else { ++ LOG(PR_LOG_DEBUG, "read metadata pipeline prerolled"); + gst_message_unref(message); + ret = NS_OK; + break; +@@ -371,23 +381,8 @@ nsresult GStreamerReader::ReadMetadata(M + /* we couldn't get this to play */ + return ret; + +- /* FIXME: workaround for a bug in matroskademux. This seek makes matroskademux +- * parse the index */ +- if (gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME, +- GST_SEEK_FLAG_FLUSH, 0)) { +- /* after a seek we need to wait again for ASYNC_DONE */ +- message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE, +- (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR)); +- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) { +- gst_element_set_state(mPlayBin, GST_STATE_NULL); +- gst_message_unref(message); +- return NS_ERROR_FAILURE; +- } +- } +- + /* report the duration */ + gint64 duration; +- GstFormat format = GST_FORMAT_TIME; + + if (isMP3 && mMP3FrameParser.IsMP3()) { + // The MP3FrameParser has reported a duration; use that over the gstreamer +@@ -396,17 +391,25 @@ nsresult GStreamerReader::ReadMetadata(M + mUseParserDuration = true; + mLastParserDuration = mMP3FrameParser.GetDuration(); + mDecoder->SetMediaDuration(mLastParserDuration); +- +- } else if (gst_element_query_duration(GST_ELEMENT(mPlayBin), +- &format, &duration) && format == GST_FORMAT_TIME) { +- // Otherwise use the gstreamer duration. +- ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); +- LOG(PR_LOG_DEBUG, "returning duration %" GST_TIME_FORMAT, GST_TIME_ARGS(duration)); +- duration = GST_TIME_AS_USECONDS (duration); +- mDecoder->SetMediaDuration(duration); +- + } else { +- mDecoder->SetMediaSeekable(false); ++ LOG(PR_LOG_DEBUG, "querying duration"); ++ // Otherwise use the gstreamer duration. ++#if GST_VERSION_MAJOR >= 1 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ GST_FORMAT_TIME, &duration)) { ++#else ++ GstFormat format = GST_FORMAT_TIME; ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ &format, &duration) && format == GST_FORMAT_TIME) { ++#endif ++ ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); ++ LOG(PR_LOG_DEBUG, "have duration %" GST_TIME_FORMAT, ++ GST_TIME_ARGS (duration)); ++ duration = GST_TIME_AS_USECONDS (duration); ++ mDecoder->SetMediaDuration(duration); ++ } else { ++ mDecoder->SetMediaSeekable(false); ++ } + } + + int n_video = 0, n_audio = 0; +@@ -419,7 +422,11 @@ nsresult GStreamerReader::ReadMetadata(M + *aTags = nullptr; + + // Watch the pipeline for fatal errors ++#if GST_VERSION_MAJOR >= 1 ++ gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this, nullptr); ++#else + gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this); ++#endif + + /* set the pipeline to PLAYING so that it starts decoding and queueing data in + * the appsinks */ +@@ -433,19 +440,35 @@ nsresult GStreamerReader::CheckSupported + bool done = false; + bool unsupported = false; + +- GstIterator *it = gst_bin_iterate_recurse(GST_BIN(mPlayBin)); ++ GstIterator* it = gst_bin_iterate_recurse(GST_BIN(mPlayBin)); + while (!done) { ++ GstIteratorResult res; + GstElement* element; +- GstIteratorResult res = gst_iterator_next(it, (void **)&element); ++ ++#if GST_VERSION_MAJOR >= 1 ++ GValue value = {0,}; ++ res = gst_iterator_next(it, &value); ++#else ++ res = gst_iterator_next(it, (void **) &element); ++#endif + switch(res) { + case GST_ITERATOR_OK: + { ++#if GST_VERSION_MAJOR >= 1 ++ element = GST_ELEMENT (g_value_get_object (&value)); ++#endif + GstElementFactory* factory = gst_element_get_factory(element); + if (factory) { + const char* klass = gst_element_factory_get_klass(factory); +- GstPad* pad = gst_element_get_pad(element, "sink"); ++ GstPad* pad = gst_element_get_static_pad(element, "sink"); + if (pad) { +- GstCaps* caps = gst_pad_get_negotiated_caps(pad); ++ GstCaps* caps; ++ ++#if GST_VERSION_MAJOR >= 1 ++ caps = gst_pad_get_current_caps(pad); ++#else ++ caps = gst_pad_get_negotiated_caps(pad); ++#endif + + if (caps) { + /* check for demuxers but ignore elements like id3demux */ +@@ -460,7 +483,11 @@ nsresult GStreamerReader::CheckSupported + } + } + ++#if GST_VERSION_MAJOR >= 1 ++ g_value_unset (&value); ++#else + gst_object_unref(element); ++#endif + done = unsupported; + break; + } +@@ -484,6 +511,8 @@ nsresult GStreamerReader::ResetDecode() + { + nsresult res = NS_OK; + ++ LOG(PR_LOG_DEBUG, "reset decode"); ++ + if (NS_FAILED(MediaDecoderReader::ResetDecode())) { + res = NS_ERROR_FAILURE; + } +@@ -494,6 +523,11 @@ nsresult GStreamerReader::ResetDecode() + mVideoSinkBufferCount = 0; + mAudioSinkBufferCount = 0; + mReachedEos = false; ++#if GST_VERSION_MAJOR >= 1 ++ mConfigureAlignment = true; ++#endif ++ ++ LOG(PR_LOG_DEBUG, "reset decode done"); + + return res; + } +@@ -517,11 +551,11 @@ bool GStreamerReader::DecodeAudioData() + /* We have nothing decoded so it makes no sense to return to the state machine + * as it will call us back immediately, we'll return again and so on, wasting + * CPU cycles for no job done. So, block here until there is either video or +- * audio data available ++ * audio data available + */ + mon.Wait(); + if (!mAudioSinkBufferCount) { +- /* There is still no audio data available, so either there is video data or ++ /* There is still no audio data available, so either there is video data or + * something else has happened (Eos, etc...). Return to the state machine + * to process it. + */ +@@ -533,24 +567,43 @@ bool GStreamerReader::DecodeAudioData() + } + } + ++#if GST_VERSION_MAJOR >= 1 ++ GstSample *sample = gst_app_sink_pull_sample(mAudioAppSink); ++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); ++ gst_sample_unref(sample); ++#else + buffer = gst_app_sink_pull_buffer(mAudioAppSink); ++#endif ++ + mAudioSinkBufferCount--; + } + + int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer); + timestamp = gst_segment_to_stream_time(&mAudioSegment, + GST_FORMAT_TIME, timestamp); ++ + timestamp = GST_TIME_AS_USECONDS(timestamp); + int64_t duration = 0; + if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) + duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); + + int64_t offset = GST_BUFFER_OFFSET(buffer); ++#if GST_VERSION_MAJOR >= 1 ++ GstMapInfo info; ++ gst_buffer_map(buffer, &info, GST_MAP_READ); ++ unsigned int size = info.size; ++#else + unsigned int size = GST_BUFFER_SIZE(buffer); ++#endif + int32_t frames = (size / sizeof(AudioDataValue)) / mInfo.mAudio.mChannels; + ssize_t outSize = static_cast<size_t>(size / sizeof(AudioDataValue)); + nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outSize]); ++#if GST_VERSION_MAJOR >= 1 ++ memcpy(data, info.data, info.size); ++ gst_buffer_unmap(buffer, &info); ++#else + memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); ++#endif + AudioData* audio = new AudioData(offset, timestamp, duration, + frames, data.forget(), mInfo.mAudio.mChannels); + +@@ -561,7 +614,7 @@ bool GStreamerReader::DecodeAudioData() + } + + bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip, +- int64_t aTimeThreshold) ++ int64_t aTimeThreshold) + { + NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); + +@@ -580,11 +633,11 @@ bool GStreamerReader::DecodeVideoFrame(b + /* We have nothing decoded so it makes no sense to return to the state machine + * as it will call us back immediately, we'll return again and so on, wasting + * CPU cycles for no job done. So, block here until there is either video or +- * audio data available ++ * audio data available + */ + mon.Wait(); + if (!mVideoSinkBufferCount) { +- /* There is still no video data available, so either there is audio data or ++ /* There is still no video data available, so either there is audio data or + * something else has happened (Eos, etc...). Return to the state machine + * to process it + */ +@@ -598,11 +651,17 @@ bool GStreamerReader::DecodeVideoFrame(b + + mDecoder->NotifyDecodedFrames(0, 1); + ++#if GST_VERSION_MAJOR >= 1 ++ GstSample *sample = gst_app_sink_pull_sample(mVideoAppSink); ++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); ++ gst_sample_unref(sample); ++#else + buffer = gst_app_sink_pull_buffer(mVideoAppSink); ++#endif + mVideoSinkBufferCount--; + } + +- bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); ++ bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + if ((aKeyFrameSkip && !isKeyframe)) { + gst_buffer_unref(buffer); + return true; +@@ -618,73 +677,55 @@ bool GStreamerReader::DecodeVideoFrame(b + "frame has invalid timestamp"); + + timestamp = GST_TIME_AS_USECONDS(timestamp); ++ int64_t duration; ++ if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) ++ duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); ++ else if (fpsNum && fpsDen) ++ /* add 1-frame duration */ ++ duration = gst_util_uint64_scale(GST_USECOND, fpsDen, fpsNum); ++ + if (timestamp < aTimeThreshold) { + LOG(PR_LOG_DEBUG, "skipping frame %" GST_TIME_FORMAT +- " threshold %" GST_TIME_FORMAT, +- GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)); ++ " threshold %" GST_TIME_FORMAT, ++ GST_TIME_ARGS(timestamp * 1000), ++ GST_TIME_ARGS(aTimeThreshold * 1000)); + gst_buffer_unref(buffer); + return true; + } +- + if (!buffer) + /* no more frames */ + return false; + +- int64_t duration = 0; +- if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) +- duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); +- else if (fpsNum && fpsDen) +- /* 1-frame duration */ +- duration = gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen); +- +- nsRefPtr<PlanarYCbCrImage> image; +- GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*> +- GST_IS_MOZ_VIDEO_BUFFER(buffer)?gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(buffer)):nullptr; +- +- if(bufferdata) +- image = bufferdata->mImage; ++#if GST_VERSION_MAJOR >= 1 ++ if (mConfigureAlignment && buffer->pool) { ++ GstStructure *config = gst_buffer_pool_get_config(buffer->pool); ++ GstVideoAlignment align; ++ if (gst_buffer_pool_config_get_video_alignment(config, &align)) ++ gst_video_info_align(&mVideoInfo, &align); ++ gst_structure_free(config); ++ mConfigureAlignment = false; ++ } ++#endif + ++ nsRefPtr<PlanarYCbCrImage> image = GetImageFromBuffer(buffer); + if (!image) { + /* Ugh, upstream is not calling gst_pad_alloc_buffer(). Fallback to + * allocating a PlanarYCbCrImage backed GstBuffer here and memcpy. + */ + GstBuffer* tmp = nullptr; +- AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(buffer), +- GST_BUFFER_SIZE(buffer), nullptr, &tmp, image); +- +- /* copy */ +- gst_buffer_copy_metadata(tmp, buffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL); +- memcpy(GST_BUFFER_DATA(tmp), GST_BUFFER_DATA(buffer), +- GST_BUFFER_SIZE(tmp)); ++ CopyIntoImageBuffer(buffer, &tmp, image); + gst_buffer_unref(buffer); + buffer = tmp; + } + +- guint8* data = GST_BUFFER_DATA(buffer); +- +- int width = mPicture.width; +- int height = mPicture.height; +- GstVideoFormat format = mFormat; +- +- VideoData::YCbCrBuffer b; +- for(int i = 0; i < 3; i++) { +- b.mPlanes[i].mData = data + gst_video_format_get_component_offset(format, i, +- width, height); +- b.mPlanes[i].mStride = gst_video_format_get_row_stride(format, i, width); +- b.mPlanes[i].mHeight = gst_video_format_get_component_height(format, +- i, height); +- b.mPlanes[i].mWidth = gst_video_format_get_component_width(format, +- i, width); +- b.mPlanes[i].mOffset = 0; +- b.mPlanes[i].mSkip = 0; +- } +- +- isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + int64_t offset = mDecoder->GetResource()->Tell(); // Estimate location in media. +- VideoData* video = VideoData::Create(mInfo.mVideo, image, offset, +- timestamp, duration, b, +- isKeyframe, -1, mPicture); ++ VideoData* video = VideoData::CreateFromImage(mInfo.mVideo, ++ mDecoder->GetImageContainer(), ++ offset, timestamp, duration, ++ static_cast<Image*>(image.get()), ++ isKeyframe, -1, mPicture); + mVideoQueue.Push(video); ++ + gst_buffer_unref(buffer); + + return true; +@@ -707,6 +748,10 @@ nsresult GStreamerReader::Seek(int64_t a + return NS_ERROR_FAILURE; + } + LOG(PR_LOG_DEBUG, "seek succeeded"); ++ GstMessage* message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE, ++ (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR)); ++ gst_message_unref(message); ++ LOG(PR_LOG_DEBUG, "seek completed"); + + return DecodeToTarget(aTarget); + } +@@ -718,7 +763,9 @@ nsresult GStreamerReader::GetBuffered(do + return NS_OK; + } + ++#if GST_VERSION_MAJOR == 0 + GstFormat format = GST_FORMAT_TIME; ++#endif + MediaResource* resource = mDecoder->GetResource(); + nsTArray<MediaByteRange> ranges; + resource->GetCachedRanges(ranges); +@@ -740,12 +787,21 @@ nsresult GStreamerReader::GetBuffered(do + int64_t endOffset = ranges[index].mEnd; + gint64 startTime, endTime; + ++#if GST_VERSION_MAJOR >= 1 ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, ++ startOffset, GST_FORMAT_TIME, &startTime)) ++ continue; ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, ++ endOffset, GST_FORMAT_TIME, &endTime)) ++ continue; ++#else + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, + startOffset, &format, &startTime) || format != GST_FORMAT_TIME) + continue; + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, + endOffset, &format, &endTime) || format != GST_FORMAT_TIME) + continue; ++#endif + + double start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND; + double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND; +@@ -766,7 +822,13 @@ void GStreamerReader::ReadAndPushData(gu + nsresult rv = NS_OK; + + GstBuffer* buffer = gst_buffer_new_and_alloc(aLength); ++#if GST_VERSION_MAJOR >= 1 ++ GstMapInfo info; ++ gst_buffer_map(buffer, &info, GST_MAP_WRITE); ++ guint8 *data = info.data; ++#else + guint8* data = GST_BUFFER_DATA(buffer); ++#endif + uint32_t size = 0, bytesRead = 0; + while(bytesRead < aLength) { + rv = resource->Read(reinterpret_cast<char*>(data + bytesRead), +@@ -780,7 +842,12 @@ void GStreamerReader::ReadAndPushData(gu + int64_t offset2 = resource->Tell(); + unused << offset2; + ++#if GST_VERSION_MAJOR >= 1 ++ gst_buffer_unmap(buffer, &info); ++ gst_buffer_set_size(buffer, bytesRead); ++#else + GST_BUFFER_SIZE(buffer) = bytesRead; ++#endif + + GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer)); + if (ret != GST_FLOW_OK) { +@@ -813,8 +880,13 @@ int64_t GStreamerReader::QueryDuration() + gint64 duration = 0; + GstFormat format = GST_FORMAT_TIME; + ++#if GST_VERSION_MAJOR >= 1 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ format, &duration)) { ++#else + if (gst_element_query_duration(GST_ELEMENT(mPlayBin), + &format, &duration)) { ++#endif + if (format == GST_FORMAT_TIME) { + LOG(PR_LOG_DEBUG, "pipeline duration %" GST_TIME_FORMAT, + GST_TIME_ARGS (duration)); +@@ -893,108 +965,6 @@ gboolean GStreamerReader::SeekData(GstAp + return NS_SUCCEEDED(rv); + } + +-gboolean GStreamerReader::EventProbeCb(GstPad* aPad, +- GstEvent* aEvent, +- gpointer aUserData) +-{ +- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData); +- return reader->EventProbe(aPad, aEvent); +-} +- +-gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent) +-{ +- GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); +- switch(GST_EVENT_TYPE(aEvent)) { +- case GST_EVENT_NEWSEGMENT: +- { +- gboolean update; +- gdouble rate; +- GstFormat format; +- gint64 start, stop, position; +- GstSegment* segment; +- +- /* Store the segments so we can convert timestamps to stream time, which +- * is what the upper layers sync on. +- */ +- ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); +- gst_event_parse_new_segment(aEvent, &update, &rate, &format, +- &start, &stop, &position); +- if (parent == GST_ELEMENT(mVideoAppSink)) +- segment = &mVideoSegment; +- else +- segment = &mAudioSegment; +- gst_segment_set_newsegment(segment, update, rate, format, +- start, stop, position); +- break; +- } +- case GST_EVENT_FLUSH_STOP: +- /* Reset on seeks */ +- ResetDecode(); +- break; +- default: +- break; +- } +- gst_object_unref(parent); +- +- return TRUE; +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf, +- nsRefPtr<PlanarYCbCrImage>& aImage) +-{ +- /* allocate an image using the container */ +- ImageContainer* container = mDecoder->GetImageContainer(); +- if (!container) { +- // We don't have an ImageContainer. We probably belong to an <audio> +- // element. +- return GST_FLOW_NOT_SUPPORTED; +- } +- ImageFormat format = PLANAR_YCBCR; +- PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); +- nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img); +- +- /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */ +- GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new()); +- GST_BUFFER_SIZE(buf) = aSize; +- /* allocate the actual YUV buffer */ +- GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize); +- +- aImage = image; +- +- /* create a GstMozVideoBufferData to hold the image */ +- GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image); +- +- /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */ +- gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata); +- +- *aBuf = buf; +- return GST_FLOW_OK; +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf) +-{ +- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); +- return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf); +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf) +-{ +- nsRefPtr<PlanarYCbCrImage> image; +- return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image); +-} +- + GstFlowReturn GStreamerReader::NewPrerollCb(GstAppSink* aSink, + gpointer aUserData) + { +@@ -1011,8 +981,12 @@ void GStreamerReader::AudioPreroll() + { + /* The first audio buffer has reached the audio sink. Get rate and channels */ + LOG(PR_LOG_DEBUG, "Audio preroll"); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++#if GST_VERSION_MAJOR >= 1 ++ GstCaps *caps = gst_pad_get_current_caps(sinkpad); ++#else + GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad); ++#endif + GstStructure* s = gst_caps_get_structure(caps, 0); + mInfo.mAudio.mRate = mInfo.mAudio.mChannels = 0; + gst_structure_get_int(s, "rate", (gint*) &mInfo.mAudio.mRate); +@@ -1030,9 +1004,18 @@ void GStreamerReader::VideoPreroll() + { + /* The first video buffer has reached the video sink. Get width and height */ + LOG(PR_LOG_DEBUG, "Video preroll"); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++#if GST_VERSION_MAJOR >= 1 ++ GstCaps* caps = gst_pad_get_current_caps(sinkpad); ++ memset (&mVideoInfo, 0, sizeof (mVideoInfo)); ++ gst_video_info_from_caps(&mVideoInfo, caps); ++ mFormat = mVideoInfo.finfo->format; ++ mPicture.width = mVideoInfo.width; ++ mPicture.height = mVideoInfo.height; ++#else + GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad); + gst_video_format_parse_caps(caps, &mFormat, &mPicture.width, &mPicture.height); ++#endif + GstStructure* structure = gst_caps_get_structure(caps, 0); + gst_structure_get_fraction(structure, "framerate", &fpsNum, &fpsDen); + NS_ASSERTION(mPicture.width && mPicture.height, "invalid video resolution"); +@@ -1061,6 +1044,7 @@ void GStreamerReader::NewVideoBuffer() + /* We have a new video buffer queued in the video sink. Increment the counter + * and notify the decode thread potentially blocked in DecodeVideoFrame + */ ++ + mDecoder->NotifyDecodedFrames(1, 0); + mVideoSinkBufferCount++; + mon.NotifyAll(); +@@ -1197,5 +1181,199 @@ void GStreamerReader::NotifyDataArrived( + } + } + ++#if GST_VERSION_MAJOR >= 1 ++GstCaps* GStreamerReader::BuildAudioSinkCaps() ++{ ++ GstCaps* caps = gst_caps_from_string("audio/x-raw, channels={1,2}"); ++ const char* format; ++#ifdef MOZ_SAMPLE_TYPE_FLOAT32 ++#ifdef IS_LITTLE_ENDIAN ++ format = "F32LE"; ++#else ++ format = "F32BE"; ++#endif ++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */ ++#ifdef IS_LITTLE_ENDIAN ++ format = "S16LE"; ++#else ++ format = "S16BE"; ++#endif ++#endif ++ gst_caps_set_simple(caps, "format", G_TYPE_STRING, format, nullptr); ++ ++ return caps; ++} ++ ++void GStreamerReader::InstallPadCallbacks() ++{ ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ ++ gst_pad_add_probe(sinkpad, ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | ++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_FLUSH), ++ &GStreamerReader::EventProbeCb, this, nullptr); ++ gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, ++ GStreamerReader::QueryProbeCb, nullptr, nullptr); ++ ++ gst_pad_set_element_private(sinkpad, this); ++ gst_object_unref(sinkpad); ++ ++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ gst_pad_add_probe(sinkpad, ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | ++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_FLUSH), ++ &GStreamerReader::EventProbeCb, this, nullptr); ++ gst_object_unref(sinkpad); ++} ++ ++GstPadProbeReturn GStreamerReader::EventProbeCb(GstPad *aPad, ++ GstPadProbeInfo *aInfo, ++ gpointer aUserData) ++{ ++ GStreamerReader *reader = (GStreamerReader *) aUserData; ++ GstEvent *aEvent = (GstEvent *)aInfo->data; ++ return reader->EventProbe(aPad, aEvent); ++} ++ ++GstPadProbeReturn GStreamerReader::EventProbe(GstPad *aPad, GstEvent *aEvent) ++{ ++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); ++ ++ LOG(PR_LOG_DEBUG, "event probe %s", GST_EVENT_TYPE_NAME (aEvent)); ++ ++ switch(GST_EVENT_TYPE(aEvent)) { ++ case GST_EVENT_SEGMENT: ++ { ++ const GstSegment *newSegment; ++ GstSegment* segment; ++ ++ /* Store the segments so we can convert timestamps to stream time, which ++ * is what the upper layers sync on. ++ */ ++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); ++#if GST_VERSION_MINOR <= 1 && GST_VERSION_MICRO < 1 ++ ResetDecode(); ++#endif ++ gst_event_parse_segment(aEvent, &newSegment); ++ if (parent == GST_ELEMENT(mVideoAppSink)) ++ segment = &mVideoSegment; ++ else ++ segment = &mAudioSegment; ++ gst_segment_copy_into (newSegment, segment); ++ break; ++ } ++ case GST_EVENT_FLUSH_STOP: ++ /* Reset on seeks */ ++ ResetDecode(); ++ break; ++ default: ++ break; ++ } ++ gst_object_unref(parent); ++ ++ return GST_PAD_PROBE_OK; ++} ++ ++GstPadProbeReturn GStreamerReader::QueryProbeCb(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); ++ return reader->QueryProbe(aPad, aInfo, aUserData); ++} ++ ++GstPadProbeReturn GStreamerReader::QueryProbe(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData) ++{ ++ GstQuery *query = gst_pad_probe_info_get_query(aInfo); ++ GstPadProbeReturn ret = GST_PAD_PROBE_OK; ++ ++ switch (GST_QUERY_TYPE (query)) { ++ case GST_QUERY_ALLOCATION: ++ GstCaps *caps; ++ GstVideoInfo info; ++ gboolean need_pool; ++ ++ gst_query_parse_allocation(query, &caps, &need_pool); ++ gst_video_info_init(&info); ++ gst_video_info_from_caps(&info, caps); ++ gst_query_add_allocation_param(query, mAllocator, nullptr); ++ gst_query_add_allocation_pool(query, mBufferPool, info.size, 0, 0); ++ gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, nullptr); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++void GStreamerReader::ImageDataFromVideoFrame(GstVideoFrame *aFrame, ++ PlanarYCbCrImage::Data *aData) ++{ ++ NS_ASSERTION(GST_VIDEO_INFO_IS_YUV(&mVideoInfo), ++ "Non-YUV video frame formats not supported"); ++ NS_ASSERTION(GST_VIDEO_FRAME_N_COMPONENTS(aFrame) == 3, ++ "Unsupported number of components in video frame"); ++ ++ aData->mPicX = aData->mPicY = 0; ++ aData->mPicSize = nsIntSize(mPicture.width, mPicture.height); ++ aData->mStereoMode = STEREO_MODE_MONO; ++ ++ aData->mYChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 0); ++ aData->mYStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 0); ++ aData->mYSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 0), ++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 0)); ++ aData->mYSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 0) - 1; ++ aData->mCbCrStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 1); ++ aData->mCbCrSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 1), ++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 1)); ++ aData->mCbChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 1); ++ aData->mCrChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 2); ++ aData->mCbSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 1) - 1; ++ aData->mCrSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 2) - 1; ++} ++ ++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer) ++{ ++ nsRefPtr<PlanarYCbCrImage> image = nullptr; ++ ++ if (gst_buffer_n_memory(aBuffer) == 1) { ++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); ++ if (GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator)) { ++ image = moz_gfx_memory_get_image(mem); ++ ++ GstVideoFrame frame; ++ gst_video_frame_map(&frame, &mVideoInfo, aBuffer, GST_MAP_READ); ++ PlanarYCbCrImage::Data data; ++ ImageDataFromVideoFrame(&frame, &data); ++ image->SetDataNoCopy(data); ++ gst_video_frame_unmap(&frame); ++ } ++ } ++ ++ return image; ++} ++ ++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer, ++ GstBuffer** aOutBuffer, ++ nsRefPtr<PlanarYCbCrImage> &image) ++{ ++ *aOutBuffer = gst_buffer_new_allocate(mAllocator, gst_buffer_get_size(aBuffer), nullptr); ++ GstMemory *mem = gst_buffer_peek_memory(*aOutBuffer, 0); ++ GstMapInfo map_info; ++ gst_memory_map(mem, &map_info, GST_MAP_WRITE); ++ gst_buffer_extract(aBuffer, 0, map_info.data, gst_buffer_get_size(aBuffer)); ++ gst_memory_unmap(mem, &map_info); ++ ++ /* create a new gst buffer with the newly created memory and copy the ++ * metadata over from the incoming buffer */ ++ gst_buffer_copy_into(*aOutBuffer, aBuffer, ++ (GstBufferCopyFlags)(GST_BUFFER_COPY_METADATA), 0, -1); ++ image = GetImageFromBuffer(*aOutBuffer); ++} ++#endif ++ + } // namespace mozilla + diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.h b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.h new file mode 100644 index 00000000000..0f400b179fa --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_GStreamerReader.h @@ -0,0 +1,103 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_GStreamerReader.h,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/GStreamerReader.h.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/GStreamerReader.h +@@ -22,6 +22,7 @@ + + #include "MediaDecoderReader.h" + #include "MP3FrameParser.h" ++#include "ImageContainer.h" + #include "nsRect.h" + + namespace mozilla { +@@ -30,10 +31,6 @@ namespace dom { + class TimeRanges; + } + +-namespace layers { +-class PlanarYCbCrImage; +-} +- + class AbstractMediaDecoder; + + class GStreamerReader : public MediaDecoderReader +@@ -67,10 +64,20 @@ public: + return mInfo.HasVideo(); + } + ++ layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); } ++ + private: + + void ReadAndPushData(guint aLength); + int64_t QueryDuration(); ++ nsRefPtr<layers::PlanarYCbCrImage> GetImageFromBuffer(GstBuffer* aBuffer); ++ void CopyIntoImageBuffer(GstBuffer *aBuffer, GstBuffer** aOutBuffer, nsRefPtr<layers::PlanarYCbCrImage> &image); ++ GstCaps* BuildAudioSinkCaps(); ++ void InstallPadCallbacks(); ++ ++#if GST_VERSION_MAJOR >= 1 ++ void ImageDataFromVideoFrame(GstVideoFrame *aFrame, layers::PlanarYCbCrImage::Data *aData); ++#endif + + /* Called once the pipeline is setup to check that the stream only contains + * supported formats +@@ -105,20 +112,31 @@ private: + gboolean SeekData(GstAppSrc* aSrc, guint64 aOffset); + + /* Called when events reach the sinks. See inline comments */ ++#if GST_VERSION_MAJOR == 1 ++ static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++ GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent); ++#else + static gboolean EventProbeCb(GstPad* aPad, GstEvent* aEvent, gpointer aUserData); + gboolean EventProbe(GstPad* aPad, GstEvent* aEvent); ++#endif + +- /* Called when elements in the video branch of the pipeline call +- * gst_pad_alloc_buffer(). Used to provide PlanarYCbCrImage backed GstBuffers +- * to the pipeline so that a memory copy can be avoided when handling YUV +- * buffers from the pipeline to the gfx side. +- */ ++ /* Called when the video part of the pipeline allocates buffers. Used to ++ * provide PlanarYCbCrImage backed GstBuffers to the pipeline so that a memory ++ * copy can be avoided when handling YUV buffers from the pipeline to the gfx ++ * side. ++ */ ++#if GST_VERSION_MAJOR == 1 ++ static GstPadProbeReturn QueryProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++ GstPadProbeReturn QueryProbe(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++#else + static GstFlowReturn AllocateVideoBufferCb(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf); + GstFlowReturn AllocateVideoBufferFull(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf, nsRefPtr<layers::PlanarYCbCrImage>& aImage); + GstFlowReturn AllocateVideoBuffer(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf); ++#endif ++ + + /* Called when the pipeline is prerolled, that is when at start or after a + * seek, the first audio and video buffers are queued in the sinks. +@@ -167,6 +185,11 @@ private: + bool mUseParserDuration; + int64_t mLastParserDuration; + ++#if GST_VERSION_MAJOR >= 1 ++ GstAllocator *mAllocator; ++ GstBufferPool *mBufferPool; ++ GstVideoInfo mVideoInfo; ++#endif + GstElement* mPlayBin; + GstBus* mBus; + GstAppSrc* mSource; +@@ -197,6 +220,9 @@ private: + * DecodeAudioData and DecodeVideoFrame should not expect any more data + */ + bool mReachedEos; ++#if GST_VERSION_MAJOR >= 1 ++ bool mConfigureAlignment; ++#endif + int fpsNum; + int fpsDen; + }; diff --git a/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_moz.build b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_moz.build new file mode 100644 index 00000000000..4328850d0fb --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_gstreamer_moz.build @@ -0,0 +1,25 @@ +$NetBSD: patch-mozilla_content_media_gstreamer_moz.build,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/gstreamer/moz.build.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/gstreamer/moz.build +@@ -15,10 +15,19 @@ SOURCES += [ + 'GStreamerDecoder.cpp', + 'GStreamerFormatHelper.cpp', + 'GStreamerLoader.cpp', +- 'GStreamerMozVideoBuffer.cpp', + 'GStreamerReader.cpp', + ] + ++if CONFIG['GST_API_VERSION'] == '1.0': ++ SOURCES += [ ++ 'GStreamerAllocator.cpp', ++ ] ++else: ++ SOURCES += [ ++ 'GStreamerMozVideoBuffer.cpp', ++ 'GStreamerReader-0.10.cpp', ++ ] ++ + FAIL_ON_WARNINGS = True + + FINAL_LIBRARY = 'gklayout' diff --git a/www/seamonkey/patches/patch-mozilla_content_media_test_manifest.js b/www/seamonkey/patches/patch-mozilla_content_media_test_manifest.js new file mode 100644 index 00000000000..f86cf3fea6c --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_content_media_test_manifest.js @@ -0,0 +1,17 @@ +$NetBSD: patch-mozilla_content_media_test_manifest.js,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/content/media/test/manifest.js.orig 2014-03-19 01:41:47.000000000 +0000 ++++ mozilla/content/media/test/manifest.js +@@ -357,9 +357,9 @@ var gUnseekableTests = [ + { name:"bogus.duh", type:"bogus/duh"} + ]; + // Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so +-// only include it in the unseekable tests if we're on later versions of Windows. +-if (navigator.userAgent.indexOf("Windows") == -1 || +- IsWindows8OrLater()) { ++// only include it in the unseekable tests if we're on later versions of Windows. ++// This test actually only passes on win8 at the moment. ++if (navigator.userAgent.indexOf("Windows") != -1 && IsWindows8OrLater()) { + gUnseekableTests = gUnseekableTests.concat([ + { name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" } + ]); diff --git a/www/seamonkey/patches/patch-mozilla_dom_system_OSFileConstants.cpp b/www/seamonkey/patches/patch-mozilla_dom_system_OSFileConstants.cpp new file mode 100644 index 00000000000..6be3ec20e73 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_dom_system_OSFileConstants.cpp @@ -0,0 +1,32 @@ +$NetBSD: patch-mozilla_dom_system_OSFileConstants.cpp,v 1.3 2014/03/30 04:13:17 ryoon Exp $ + +* NetBSD 5 does not support posix_spawn(3) + +--- mozilla/dom/system/OSFileConstants.cpp.orig 2014-03-15 05:19:14.000000000 +0000 ++++ mozilla/dom/system/OSFileConstants.cpp +@@ -9,11 +9,15 @@ + + #include "prsystem.h" + ++#if defined(__NetBSD__) ++#include <sys/param.h> ++#endif ++ + #if defined(XP_UNIX) + #include "unistd.h" + #include "dirent.h" + #include "sys/stat.h" +-#if !defined(ANDROID) ++#if !defined(ANDROID) && (defined(__NetBSD_) && (__NetBSD_Version__ < 600000000)) + #include <spawn.h> + #endif // !defined(ANDROID) + #endif // defined(XP_UNIX) +@@ -508,7 +512,7 @@ static const dom::ConstantSpec gLibcProp + // The size of |time_t|. + { "OSFILE_SIZEOF_TIME_T", INT_TO_JSVAL(sizeof (time_t)) }, + +-#if !defined(ANDROID) ++#if !defined(ANDROID) && (defined(__NetBSD_) && (__NetBSD_Version__ < 600000000)) + // The size of |posix_spawn_file_actions_t|. + { "OSFILE_SIZEOF_POSIX_SPAWN_FILE_ACTIONS_T", INT_TO_JSVAL(sizeof (posix_spawn_file_actions_t)) }, + #endif // !defined(ANDROID) diff --git a/www/seamonkey/patches/patch-mozilla_extensions_auth_nsAuthGSSAPI.cpp b/www/seamonkey/patches/patch-mozilla_extensions_auth_nsAuthGSSAPI.cpp deleted file mode 100644 index 7213aba9db9..00000000000 --- a/www/seamonkey/patches/patch-mozilla_extensions_auth_nsAuthGSSAPI.cpp +++ /dev/null @@ -1,14 +0,0 @@ -$NetBSD: patch-mozilla_extensions_auth_nsAuthGSSAPI.cpp,v 1.1 2013/05/23 13:25:30 ryoon Exp $ - ---- mozilla/extensions/auth/nsAuthGSSAPI.cpp.orig 2013-05-03 03:07:54.000000000 +0000 -+++ mozilla/extensions/auth/nsAuthGSSAPI.cpp -@@ -39,6 +39,9 @@ typedef KLStatus (*KLCacheHasValidTicket - #endif - - #if defined(HAVE_RES_NINIT) -+#include <sys/types.h> -+#include <netinet/in.h> -+#include <arpa/nameser.h> - #include <resolv.h> - #endif - diff --git a/www/seamonkey/patches/patch-mozilla_gfx_moz.build b/www/seamonkey/patches/patch-mozilla_gfx_moz.build new file mode 100644 index 00000000000..fa9ee2bb943 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_gfx_moz.build @@ -0,0 +1,26 @@ +$NetBSD: patch-mozilla_gfx_moz.build,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/gfx/moz.build.orig 2014-03-19 01:41:53.000000000 +0000 ++++ mozilla/gfx/moz.build +@@ -7,6 +7,12 @@ + if CONFIG['MOZ_TREE_CAIRO']: + DIRS += ['cairo'] + ++if not CONFIG['MOZ_NATIVE_GRAPHITE2']: ++ DIRS += ['graphite2/src' ] ++ ++if not CONFIG['MOZ_NATIVE_HARFBUZZ']: ++ DIRS += ['harfbuzz/src'] ++ + DIRS += [ + '2d', + 'ycbcr', +@@ -15,8 +21,6 @@ DIRS += [ + 'qcms', + 'gl', + 'layers', +- 'graphite2/src', +- 'harfbuzz/src', + 'ots/src', + 'thebes', + 'ipc', diff --git a/www/seamonkey/patches/patch-mozilla_gfx_skia_Makefile.in b/www/seamonkey/patches/patch-mozilla_gfx_skia_Makefile.in new file mode 100644 index 00000000000..36f159d4259 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_gfx_skia_Makefile.in @@ -0,0 +1,15 @@ +$NetBSD: patch-mozilla_gfx_skia_Makefile.in,v 1.3 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/gfx/skia/Makefile.in.orig 2014-03-19 01:41:53.000000000 +0000 ++++ mozilla/gfx/skia/Makefile.in +@@ -34,6 +34,10 @@ ifeq (qt,$(MOZ_WIDGET_TOOLKIT)) + OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS) + endif + ++ifdef MOZ_NATIVE_HARFBUZZ ++OS_CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + include $(topsrcdir)/config/rules.mk + + ifneq (,$(INTEL_ARCHITECTURE)) diff --git a/www/seamonkey/patches/patch-mozilla_gfx_skia_moz.build b/www/seamonkey/patches/patch-mozilla_gfx_skia_moz.build index 1b66fa1e799..df060c089fc 100644 --- a/www/seamonkey/patches/patch-mozilla_gfx_skia_moz.build +++ b/www/seamonkey/patches/patch-mozilla_gfx_skia_moz.build @@ -1,10 +1,10 @@ -$NetBSD: patch-mozilla_gfx_skia_moz.build,v 1.2 2013/11/04 06:01:46 ryoon Exp $ +$NetBSD: patch-mozilla_gfx_skia_moz.build,v 1.3 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/gfx/skia/moz.build.orig 2013-10-29 01:20:49.000000000 +0000 +--- mozilla/gfx/skia/moz.build.orig 2014-03-19 01:41:53.000000000 +0000 +++ mozilla/gfx/skia/moz.build -@@ -197,7 +197,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt - 'SkFontHost_FreeType_common.cpp', - 'SkOSFile.cpp', +@@ -209,7 +209,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt + 'src/ports/SkFontHost_cairo.cpp', + 'src/ports/SkFontHost_FreeType_common.cpp', ] - if CONFIG['OS_TARGET'] == 'Linux': + if CONFIG['MOZ_X11'] == 1 or CONFIG['OS_TARGET'] == 'Linux': diff --git a/www/seamonkey/patches/patch-mozilla_gfx_thebes_Makefile.in b/www/seamonkey/patches/patch-mozilla_gfx_thebes_Makefile.in new file mode 100644 index 00000000000..e546086fee5 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_gfx_thebes_Makefile.in @@ -0,0 +1,19 @@ +$NetBSD: patch-mozilla_gfx_thebes_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/gfx/thebes/Makefile.in.orig 2014-03-19 01:41:54.000000000 +0000 ++++ mozilla/gfx/thebes/Makefile.in +@@ -13,6 +13,14 @@ DEFINES := $(filter-out -DUNICODE,$(DEFI + CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS) + CFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS) + ++ifdef MOZ_NATIVE_GRAPHITE2 ++CXXFLAGS += $(MOZ_GRAPHITE2_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + ifeq ($(MOZ_WIDGET_TOOLKIT),android) + CXXFLAGS += $(CAIRO_FT_CFLAGS) + endif diff --git a/www/seamonkey/patches/patch-mozilla_intl_unicharutil_util_Makefile.in b/www/seamonkey/patches/patch-mozilla_intl_unicharutil_util_Makefile.in new file mode 100644 index 00000000000..31b385f7aec --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_intl_unicharutil_util_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-mozilla_intl_unicharutil_util_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/intl/unicharutil/util/Makefile.in.orig 2014-03-19 01:41:56.000000000 +0000 ++++ mozilla/intl/unicharutil/util/Makefile.in +@@ -19,3 +19,7 @@ ifdef _MSC_VER + OS_COMPILE_CXXFLAGS += -Zl + OS_COMPILE_CFLAGS += -Zl + endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++nsUnicodePropertyData.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif diff --git a/www/seamonkey/patches/patch-mozilla_ipc_chromium_Makefile.in b/www/seamonkey/patches/patch-mozilla_ipc_chromium_Makefile.in index 3e357a6f69e..0d54bf7b9d4 100644 --- a/www/seamonkey/patches/patch-mozilla_ipc_chromium_Makefile.in +++ b/www/seamonkey/patches/patch-mozilla_ipc_chromium_Makefile.in @@ -1,8 +1,8 @@ -$NetBSD: patch-mozilla_ipc_chromium_Makefile.in,v 1.10 2013/11/04 06:01:46 ryoon Exp $ +$NetBSD: patch-mozilla_ipc_chromium_Makefile.in,v 1.11 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/ipc/chromium/Makefile.in.orig 2013-10-29 01:20:52.000000000 +0000 +--- mozilla/ipc/chromium/Makefile.in.orig 2014-03-19 01:41:56.000000000 +0000 +++ mozilla/ipc/chromium/Makefile.in -@@ -22,9 +22,7 @@ vpath %.c \ +@@ -11,9 +11,7 @@ vpath %.c \ $(srcdir)/src/third_party/libevent \ $(NULL) else # } else { @@ -13,37 +13,3 @@ $NetBSD: patch-mozilla_ipc_chromium_Makefile.in,v 1.10 2013/11/04 06:01:46 ryoon endif # } vpath %.cc \ -@@ -45,6 +43,33 @@ DEFINES += -DANDROID -D_POSIX_MONOTONIC_ - endif # Android - endif # } Not WINNT (OS_POSIX) - -+ifdef OS_SOLARIS # { -+ -+CPPSRCS += \ -+ atomicops_internals_x86_gcc.cc \ -+ process_util_linux.cc \ -+ time_posix.cc \ -+ $(NULL) -+ -+ifdef MOZ_ENABLE_GTK2 -+CPPSRCS += \ -+ message_pump_glib.cc \ -+ $(NULL) -+endif -+ -+ifdef MOZ_ENABLE_QT -+MOCSRCS = \ -+ moc_message_pump_qt.cc \ -+ $(NULL) -+ -+CPPSRCS += \ -+ $(MOCSRCS) \ -+ message_pump_qt.cc \ -+ $(NULL) -+endif -+ -+endif # } OS_SOLARIS -+ - # libevent - - ifndef MOZ_NATIVE_LIBEVENT # { diff --git a/www/seamonkey/patches/patch-mozilla_ipc_chromium_chromium-config.mk b/www/seamonkey/patches/patch-mozilla_ipc_chromium_chromium-config.mk deleted file mode 100644 index 09005967736..00000000000 --- a/www/seamonkey/patches/patch-mozilla_ipc_chromium_chromium-config.mk +++ /dev/null @@ -1,25 +0,0 @@ -$NetBSD: patch-mozilla_ipc_chromium_chromium-config.mk,v 1.9 2013/08/11 03:18:46 ryoon Exp $ - ---- mozilla/ipc/chromium/chromium-config.mk.orig 2013-08-04 03:05:29.000000000 +0000 -+++ mozilla/ipc/chromium/chromium-config.mk -@@ -105,6 +105,14 @@ DEFINES += \ - $(NULL) - - else # } { -+ifeq ($(OS_ARCH),SunOS) # { -+ -+OS_SOLARIS = 1 -+DEFINES += \ -+ -DOS_SOLARIS=1 \ -+ $(NULL) -+ -+else # } { - - OS_LINUX = 1 - DEFINES += \ -@@ -117,4 +125,5 @@ endif # } - endif # } - endif # } - endif # } -+endif # } - diff --git a/www/seamonkey/patches/patch-mozilla_ipc_glue_AsyncChannel.cpp b/www/seamonkey/patches/patch-mozilla_ipc_glue_AsyncChannel.cpp deleted file mode 100644 index 9beb38f64d0..00000000000 --- a/www/seamonkey/patches/patch-mozilla_ipc_glue_AsyncChannel.cpp +++ /dev/null @@ -1,22 +0,0 @@ -$NetBSD: patch-mozilla_ipc_glue_AsyncChannel.cpp,v 1.1 2013/08/11 03:18:46 ryoon Exp $ - ---- mozilla/ipc/glue/AsyncChannel.cpp.orig 2013-08-04 03:05:30.000000000 +0000 -+++ mozilla/ipc/glue/AsyncChannel.cpp -@@ -709,7 +709,7 @@ AsyncChannel::ProcessLink::OnChannelOpen - mExistingListener = mTransport->set_listener(this); - #ifdef DEBUG - if (mExistingListener) { -- queue<Message> pending; -+ std::queue<Message> pending; - mExistingListener->GetQueuedMessages(pending); - MOZ_ASSERT(pending.empty()); - } -@@ -726,7 +726,7 @@ AsyncChannel::ProcessLink::OnTakeConnect - { - AssertIOThread(); - -- queue<Message> pending; -+ std::queue<Message> pending; - { - MonitorAutoLock lock(*mChan->mMonitor); - diff --git a/www/seamonkey/patches/patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp b/www/seamonkey/patches/patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp index 658a8707624..8f2baeb4f79 100644 --- a/www/seamonkey/patches/patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp +++ b/www/seamonkey/patches/patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp @@ -1,6 +1,6 @@ -$NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.8 2013/08/11 03:18:46 ryoon Exp $ +$NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.9 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/ipc/glue/GeckoChildProcessHost.cpp.orig 2013-08-04 03:05:30.000000000 +0000 +--- mozilla/ipc/glue/GeckoChildProcessHost.cpp.orig 2014-03-19 01:41:56.000000000 +0000 +++ mozilla/ipc/glue/GeckoChildProcessHost.cpp @@ -4,7 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -14,9 +14,9 @@ $NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.8 2013/08/11 03:18 +_Pragma("GCC visibility pop") +#endif - #include "base/command_line.h" - #include "base/path_service.h" -@@ -490,7 +496,7 @@ GeckoChildProcessHost::PerformAsyncLaunc + #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + #include "sandboxBroker.h" +@@ -499,7 +505,7 @@ GeckoChildProcessHost::PerformAsyncLaunc // and passing wstrings from one config to the other is unsafe. So // we split the logic here. @@ -25,7 +25,7 @@ $NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.8 2013/08/11 03:18 base::environment_map newEnvVars; ChildPrivileges privs = mPrivileges; if (privs == base::PRIVILEGES_DEFAULT) { -@@ -509,7 +515,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -518,7 +524,7 @@ GeckoChildProcessHost::PerformAsyncLaunc if (NS_SUCCEEDED(rv)) { nsCString path; greDir->GetNativePath(path); @@ -34,7 +34,7 @@ $NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.8 2013/08/11 03:18 # if defined(MOZ_WIDGET_ANDROID) path += "/lib"; # endif // MOZ_WIDGET_ANDROID -@@ -618,7 +624,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -627,7 +633,7 @@ GeckoChildProcessHost::PerformAsyncLaunc childArgv.push_back(pidstring); #if defined(MOZ_CRASHREPORTER) @@ -43,7 +43,7 @@ $NetBSD: patch-mozilla_ipc_glue_GeckoChildProcessHost.cpp,v 1.8 2013/08/11 03:18 int childCrashFd, childCrashRemapFd; if (!CrashReporter::CreateNotificationPipeForChild( &childCrashFd, &childCrashRemapFd)) -@@ -651,7 +657,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -660,7 +666,7 @@ GeckoChildProcessHost::PerformAsyncLaunc childArgv.push_back(childProcessType); base::LaunchApp(childArgv, mFileMap, diff --git a/www/seamonkey/patches/patch-mozilla_js_src_Makefile.in b/www/seamonkey/patches/patch-mozilla_js_src_Makefile.in index 038f1c24641..cb008cfe822 100644 --- a/www/seamonkey/patches/patch-mozilla_js_src_Makefile.in +++ b/www/seamonkey/patches/patch-mozilla_js_src_Makefile.in @@ -1,18 +1,13 @@ -$NetBSD: patch-mozilla_js_src_Makefile.in,v 1.4 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_js_src_Makefile.in,v 1.5 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/js/src/Makefile.in.orig 2013-12-11 04:28:40.000000000 +0000 +--- mozilla/js/src/Makefile.in.orig 2014-03-19 01:41:57.000000000 +0000 +++ mozilla/js/src/Makefile.in -@@ -467,6 +467,13 @@ EXTRA_LIBS += -lposix4 -ldl -lnsl -lsock - endif +@@ -379,7 +379,7 @@ endif + ifdef MOZ_SHARED_ICU + EXTRA_DSO_LDOPTS += $(MOZ_ICU_LIBS) + else +-SHARED_LIBRARY_LIBS += $(MOZ_ICU_LIBS) ++SHARED_LIBRARY_LIBS += $(filter-out -L% -l% -Wl%,$(MOZ_ICU_LIBS)) endif -+# clang 3.3 + -O2 makes jaeger crash in FixupArity -+ifdef CLANG_CXX -+ifndef MOZ_DEBUG -+Compiler.$(OBJ_SUFFIX): CXXFLAGS += -fno-inline-functions -+endif -+endif -+ - # An AIX Optimization bug causes PR_dtoa() & JS_dtoa to produce wrong result. - # This suppresses optimization for this single compilation unit. - ifeq ($(OS_ARCH),AIX) + # Prevent floating point errors caused by VC++ optimizations diff --git a/www/seamonkey/patches/patch-mozilla_js_src_config_system-headers b/www/seamonkey/patches/patch-mozilla_js_src_config_system-headers index e25d214f4c9..f1a00e25e53 100644 --- a/www/seamonkey/patches/patch-mozilla_js_src_config_system-headers +++ b/www/seamonkey/patches/patch-mozilla_js_src_config_system-headers @@ -1,9 +1,10 @@ -$NetBSD: patch-mozilla_js_src_config_system-headers,v 1.9 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_js_src_config_system-headers,v 1.10 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/js/src/config/system-headers.orig 2013-12-11 04:28:40.000000000 +0000 +--- mozilla/js/src/config/system-headers.orig 2014-03-19 01:41:57.000000000 +0000 +++ mozilla/js/src/config/system-headers -@@ -1144,3 +1144,4 @@ unicode/unum.h - unicode/ustring.h +@@ -1145,3 +1145,5 @@ unicode/ustring.h unicode/utypes.h #endif -+libutil.h + libutil.h ++unwind.h ++cairo-qt.h diff --git a/www/seamonkey/patches/patch-mozilla_js_src_ctypes_CTypes.h b/www/seamonkey/patches/patch-mozilla_js_src_ctypes_CTypes.h index e1a88376818..220890f4537 100644 --- a/www/seamonkey/patches/patch-mozilla_js_src_ctypes_CTypes.h +++ b/www/seamonkey/patches/patch-mozilla_js_src_ctypes_CTypes.h @@ -1,10 +1,10 @@ -$NetBSD: patch-mozilla_js_src_ctypes_CTypes.h,v 1.1 2013/09/28 14:37:05 ryoon Exp $ +$NetBSD: patch-mozilla_js_src_ctypes_CTypes.h,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/js/src/ctypes/CTypes.h.orig 2013-09-16 18:26:39.000000000 +0000 +--- mozilla/js/src/ctypes/CTypes.h.orig 2014-03-19 01:41:57.000000000 +0000 +++ mozilla/js/src/ctypes/CTypes.h -@@ -13,6 +13,23 @@ - - #include "js/HashTable.h" +@@ -14,6 +14,23 @@ + #include "js/Vector.h" + #include "vm/String.h" +#if defined(__NetBSD__) +#include <stdint.h> diff --git a/www/seamonkey/patches/patch-mozilla_js_src_jit_AsmJSSignalHandlers.cpp b/www/seamonkey/patches/patch-mozilla_js_src_jit_AsmJSSignalHandlers.cpp deleted file mode 100644 index bc70a0c2bcb..00000000000 --- a/www/seamonkey/patches/patch-mozilla_js_src_jit_AsmJSSignalHandlers.cpp +++ /dev/null @@ -1,26 +0,0 @@ -$NetBSD: patch-mozilla_js_src_jit_AsmJSSignalHandlers.cpp,v 1.1 2013/09/28 14:37:05 ryoon Exp $ - ---- mozilla/js/src/jit/AsmJSSignalHandlers.cpp.orig 2013-09-16 18:26:40.000000000 +0000 -+++ mozilla/js/src/jit/AsmJSSignalHandlers.cpp -@@ -59,10 +59,11 @@ using namespace mozilla; - #elif defined(__linux__) || defined(SOLARIS) - # if defined(__linux__) - # define XMM_sig(p,i) ((p)->uc_mcontext.fpregs->_xmm[i]) -+# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_EIP]) - # else - # define XMM_sig(p,i) ((p)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[i]) -+# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_PC]) - # endif --# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_EIP]) - # define RIP_sig(p) ((p)->uc_mcontext.gregs[REG_RIP]) - # define PC_sig(p) ((p)->uc_mcontext.arm_pc) - # define RAX_sig(p) ((p)->uc_mcontext.gregs[REG_RAX]) -@@ -269,7 +270,7 @@ LookupHeapAccess(const AsmJSModule &modu - # if defined(JS_CPU_X64) - # if defined(__DragonFly__) - # include <machine/npx.h> // for union savefpu --# elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__) -+# elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) - # include <machine/fpu.h> // for struct savefpu/fxsave64 - # endif - # endif diff --git a/www/seamonkey/patches/patch-mozilla_js_src_jscompartment.h b/www/seamonkey/patches/patch-mozilla_js_src_jscompartment.h deleted file mode 100644 index 9834639770b..00000000000 --- a/www/seamonkey/patches/patch-mozilla_js_src_jscompartment.h +++ /dev/null @@ -1,16 +0,0 @@ -$NetBSD: patch-mozilla_js_src_jscompartment.h,v 1.2 2013/07/12 12:24:10 ryoon Exp $ - ---- mozilla/js/src/jscompartment.h.orig 2013-06-20 04:35:08.000000000 +0000 -+++ mozilla/js/src/jscompartment.h -@@ -396,9 +396,9 @@ class js::AutoDebugModeGC - GC(rt, GC_NORMAL, JS::gcreason::DEBUG_MODE_GC); - } - -- void scheduleGC(Zone *zone) { -+ void scheduleGC(JS::Zone *zone) { - JS_ASSERT(!rt->isHeapBusy()); -- PrepareZoneForGC(zone); -+ JS::PrepareZoneForGC(zone); - needGC = true; - } - }; diff --git a/www/seamonkey/patches/patch-mozilla_media_libpng_pngpriv.h b/www/seamonkey/patches/patch-mozilla_media_libpng_pngpriv.h index 4125ee32d80..94c2be432ee 100644 --- a/www/seamonkey/patches/patch-mozilla_media_libpng_pngpriv.h +++ b/www/seamonkey/patches/patch-mozilla_media_libpng_pngpriv.h @@ -1,6 +1,6 @@ -$NetBSD: patch-mozilla_media_libpng_pngpriv.h,v 1.1 2013/08/11 03:18:46 ryoon Exp $ +$NetBSD: patch-mozilla_media_libpng_pngpriv.h,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/media/libpng/pngpriv.h.orig 2013-08-04 03:05:41.000000000 +0000 +--- mozilla/media/libpng/pngpriv.h.orig 2014-03-19 01:42:07.000000000 +0000 +++ mozilla/media/libpng/pngpriv.h @@ -38,6 +38,7 @@ * still required (as of 2011-05-02.) @@ -9,4 +9,4 @@ $NetBSD: patch-mozilla_media_libpng_pngpriv.h,v 1.1 2013/08/11 03:18:46 ryoon Ex +#define _XOPEN_SOURCE 600 #ifndef PNG_VERSION_INFO_ONLY - /* This is required for the definition of abort(), used as a last ditch + /* Standard library headers not required by png.h: */ diff --git a/www/seamonkey/patches/patch-mozilla_media_libtheora_Makefile.in b/www/seamonkey/patches/patch-mozilla_media_libtheora_Makefile.in new file mode 100644 index 00000000000..247e9b24c8d --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_media_libtheora_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-mozilla_media_libtheora_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/media/libtheora/Makefile.in.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/media/libtheora/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/seamonkey/patches/patch-mozilla_media_libtremor_Makefile.in b/www/seamonkey/patches/patch-mozilla_media_libtremor_Makefile.in new file mode 100644 index 00000000000..2d7b5c1eb0a --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_media_libtremor_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-mozilla_media_libtremor_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/media/libtremor/Makefile.in.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/media/libtremor/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/seamonkey/patches/patch-mozilla_media_libvorbis_Makefile.in b/www/seamonkey/patches/patch-mozilla_media_libvorbis_Makefile.in new file mode 100644 index 00000000000..740c4e991e0 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_media_libvorbis_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-mozilla_media_libvorbis_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/media/libvorbis/Makefile.in.orig 2014-03-29 04:22:17.000000000 +0000 ++++ mozilla/media/libvorbis/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_signaling_test_Makefile.in b/www/seamonkey/patches/patch-mozilla_media_webrtc_signaling_test_Makefile.in index 3ede53aea5a..ddfa69344d0 100644 --- a/www/seamonkey/patches/patch-mozilla_media_webrtc_signaling_test_Makefile.in +++ b/www/seamonkey/patches/patch-mozilla_media_webrtc_signaling_test_Makefile.in @@ -1,12 +1,25 @@ -$NetBSD: patch-mozilla_media_webrtc_signaling_test_Makefile.in,v 1.2 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_media_webrtc_signaling_test_Makefile.in,v 1.3 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/media/webrtc/signaling/test/Makefile.in.orig 2013-12-11 04:28:55.000000000 +0000 +--- mozilla/media/webrtc/signaling/test/Makefile.in.orig 2014-03-19 01:42:08.000000000 +0000 +++ mozilla/media/webrtc/signaling/test/Makefile.in -@@ -7,6 +7,7 @@ LIBS = \ - $(NSPR_LIBS) \ +@@ -8,6 +8,7 @@ LIBS = \ $(NSS_LIBS) \ $(REALTIME_LIBS) \ + $(MOZ_JS_LIBS) \ + $(MOZ_LIBV4L2_LIBS) \ $(DEPTH)/xpcom/glue/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \ $(DEPTH)/media/mtransport/standalone/$(LIB_PREFIX)mtransport_s.$(LIB_SUFFIX) \ $(DEPTH)/media/webrtc/signalingtest/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \ +@@ -40,6 +41,12 @@ LIBS += \ + $(NULL) + endif + ++ifdef MOZ_NATIVE_OPUS ++LIBS += \ ++ $(MOZ_OPUS_LIBS) \ ++ $(NULL) ++endif ++ + ifdef MOZ_NATIVE_LIBVPX + LIBS += \ + $(MOZ_LIBVPX_LIBS) \ diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi new file mode 100644 index 00000000000..b22c4043236 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi @@ -0,0 +1,17 @@ +$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi.orig 2014-03-19 01:42:08.000000000 +0000 ++++ mozilla/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi +@@ -14,9 +14,9 @@ + 'conditions': [ + ['build_with_mozilla==1', { + # Mozilla provides its own build of the opus library. +- 'include_dirs': [ +- '$(DIST)/include/opus', +- ] ++ 'cflags_mozilla': [ ++ '$(MOZ_OPUS_CFLAGS)', ++ ], + }, { + 'dependencies': [ + '<(DEPTH)/third_party/opus/opus.gyp:opus' diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc index a7692342c6a..fe1ac92b642 100644 --- a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc +++ b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc @@ -1,10 +1,10 @@ -$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.3 2013/11/04 06:01:46 ryoon Exp $ +$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.4 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2013-10-29 01:21:06.000000000 +0000 +--- mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2014-03-19 01:42:09.000000000 +0000 +++ mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc -@@ -19,18 +19,30 @@ - #include <stdlib.h> - +@@ -18,17 +18,37 @@ + #include <sys/stat.h> + #include <unistd.h> //v4l includes -#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__NetBSD__) || defined(__OpenBSD__) @@ -18,9 +18,8 @@ $NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_de +#include <libv4l2.h> +#endif - #include "ref_count.h" - #include "trace.h" - + #include "webrtc/system_wrappers/interface/ref_count.h" + #include "webrtc/system_wrappers/interface/trace.h" +#ifdef HAVE_LIBV4L2 +#define open v4l2_open @@ -31,10 +30,18 @@ $NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_de +#define munmap v4l2_munmap +#endif + ++#ifdef HAVE_LIBV4L2 ++#define open v4l2_open ++#define close v4l2_close ++#define dup v4l2_dup ++#define ioctl v4l2_ioctl ++#define mmap v4l2_mmap ++#define munmap v4l2_munmap ++#endif + namespace webrtc { - namespace videocapturemodule -@@ -137,6 +149,11 @@ int32_t DeviceInfoLinux::GetDeviceName( +@@ -136,6 +156,11 @@ int32_t DeviceInfoLinux::GetDeviceName( memset(deviceNameUTF8, 0, deviceNameLength); memcpy(cameraName, cap.card, sizeof(cap.card)); diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc index 0ee5e6e5509..6164c245b20 100644 --- a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc +++ b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc @@ -1,9 +1,9 @@ -$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.3 2013/11/04 06:01:46 ryoon Exp $ +$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.4 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2013-10-29 01:21:06.000000000 +0000 +--- mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2014-03-19 01:42:09.000000000 +0000 +++ mozilla/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc @@ -18,13 +18,16 @@ - #include <string.h> + #include <unistd.h> //v4l includes -#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) @@ -20,9 +20,9 @@ $NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_vi #include <new> -@@ -34,6 +37,15 @@ - #include "critical_section_wrapper.h" - #include "video_capture_linux.h" +@@ -34,6 +37,24 @@ + #include "webrtc/system_wrappers/interface/thread_wrapper.h" + #include "webrtc/system_wrappers/interface/trace.h" +#ifdef HAVE_LIBV4L2 +#define open v4l2_open @@ -33,6 +33,15 @@ $NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_modules_video__capture_linux_vi +#define munmap v4l2_munmap +#endif + ++#ifdef HAVE_LIBV4L2 ++#define open v4l2_open ++#define close v4l2_close ++#define dup v4l2_dup ++#define ioctl v4l2_ioctl ++#define mmap v4l2_mmap ++#define munmap v4l2_munmap ++#endif ++ namespace webrtc { namespace videocapturemodule diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_clock.cc b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_clock.cc deleted file mode 100644 index 48b21b6622a..00000000000 --- a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_clock.cc +++ /dev/null @@ -1,31 +0,0 @@ -$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_clock.cc,v 1.1 2013/12/26 13:17:37 ryoon Exp $ - ---- mozilla/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc.orig 2013-12-11 04:28:57.000000000 +0000 -+++ mozilla/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc -@@ -15,7 +15,7 @@ - #include <Windows.h> - #include <WinSock.h> - #include <MMSystem.h> --#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC)) -+#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) - #include <sys/time.h> - #include <time.h> - #endif -@@ -209,7 +209,7 @@ class WindowsRealTimeClock : public Real - WindowsHelpTimer* _helpTimer; - }; - --#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC)) -+#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) - class UnixRealTimeClock : public RealTimeClock { - public: - UnixRealTimeClock() {} -@@ -240,7 +240,7 @@ Clock* Clock::GetRealTimeClock() { - #if defined(_WIN32) - static WindowsRealTimeClock clock(&global_help_timer); - return &clock; --#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) -+#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) - static UnixRealTimeClock clock; - return &clock; - #else diff --git a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp index 91c37d5ca5f..416424d6683 100644 --- a/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp +++ b/www/seamonkey/patches/patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp @@ -1,3388 +1,18 @@ -$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.2 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.3 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2013-12-11 04:28:57.000000000 +0000 +--- mozilla/media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2014-03-19 01:42:09.000000000 +0000 +++ mozilla/media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp -@@ -1,1688 +1,1695 @@ --//Templated spread_sort library
--
--// Copyright Steven J. Ross 2001 - 2009.
--// Distributed under the Boost Software License, Version 1.0.
--// (See accompanying file LICENSE_1_0.txt or copy at
--// http://www.boost.org/LICENSE_1_0.txt)
--
--// See http://www.boost.org/ for updates, documentation, and revision history.
--
--/*
--Some improvements suggested by:
--Phil Endecott and Frank Gennari
--Cygwin fix provided by:
--Scott McMurray
--*/
--
--#ifndef BOOST_SPREAD_SORT_H
--#define BOOST_SPREAD_SORT_H
--#include <algorithm>
--#include <cstring>
--#include <vector>
--#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
--
--namespace boost {
-- namespace detail {
-- //This only works on unsigned data types
-- template <typename T>
-- inline unsigned
-- rough_log_2_size(const T& input)
-- {
-- unsigned result = 0;
-- //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance
-- while((input >> result) && (result < (8*sizeof(T)))) ++result;
-- return result;
-- }
--
-- //Gets the maximum size which we'll call spread_sort on to control worst-case performance
-- //Maintains both a minimum size to recurse and a check of distribution size versus count
-- //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead
-- inline size_t
-- get_max_count(unsigned log_range, size_t count)
-- {
-- unsigned divisor = rough_log_2_size(count);
-- //Making sure the divisor is positive
-- if(divisor > LOG_MEAN_BIN_SIZE)
-- divisor -= LOG_MEAN_BIN_SIZE;
-- else
-- divisor = 1;
-- unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor);
-- //Don't try to bitshift more than the size of an element
-- if((8*sizeof(size_t)) <= relative_width)
-- relative_width = (8*sizeof(size_t)) - 1;
-- return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ?
-- (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width);
-- }
--
-- //Find the minimum and maximum using <
-- template <class RandomAccessIter>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min)
-- {
-- min = max = current;
-- //Start from the second item, as max and min are initialized to the first
-- while(++current < last) {
-- if(*max < *current)
-- max = current;
-- else if(*current < *min)
-- min = current;
-- }
-- }
--
-- //Uses a user-defined comparison operator to find minimum and maximum
-- template <class RandomAccessIter, class compare>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp)
-- {
-- min = max = current;
-- while(++current < last) {
-- if(comp(*max, *current))
-- max = current;
-- else if(comp(*current, *min))
-- min = current;
-- }
-- }
--
-- //Gets a non-negative right bit shift to operate as a logarithmic divisor
-- inline int
-- get_log_divisor(size_t count, unsigned log_range)
-- {
-- int log_divisor;
-- //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so
-- if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS)
-- log_divisor = 0;
-- else {
-- //otherwise divide the data into an optimized number of pieces
-- log_divisor += LOG_MEAN_BIN_SIZE;
-- if(log_divisor < 0)
-- log_divisor = 0;
-- //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically
-- if((log_range - log_divisor) > MAX_SPLITS)
-- log_divisor = log_range - MAX_SPLITS;
-- }
-- return log_divisor;
-- }
--
-- template <class RandomAccessIter>
-- inline RandomAccessIter *
-- size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count)
-- {
-- //Assure space for the size of each bin, followed by initializing sizes
-- if(bin_count > bin_sizes.size())
-- bin_sizes.resize(bin_count);
-- for(size_t u = 0; u < bin_count; u++)
-- bin_sizes[u] = 0;
-- //Make sure there is space for the bins
-- cache_end = cache_offset + bin_count;
-- if(cache_end > bin_cache.size())
-- bin_cache.resize(cache_end);
-- return &(bin_cache[cache_offset]);
-- }
--
-- //Implementation for recursive integer sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data
-- //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- //max and min will be the same (the first item) iff all values are equivalent
-- if(max == min)
-- return;
-- RandomAccessIter * target_bin;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0)));
-- div_type div_min = *min >> log_divisor;
-- div_type div_max = *max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(*(current++) >> log_divisor) - div_min]++;
-- //Assign the bin positions
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- //This dominates runtime, mostly in the swap and bin lookups
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u) {
-- RandomAccessIter * local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((*current >> log_divisor) - div_min)) {
-- //3-way swap; this is about 1% faster than a 2-way swap with integers
-- //The main advantage is less copies are involved per item put in the correct place
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min);
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing; log_divisor is the remaining range
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Generic bitshift-based 3-way swapping code
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + (shift(*current, log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- //Note: we could increment current once the swap is done in this case, but that seems to impair performance
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- //Standard swapping wrapper for ascending values
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min);
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min, comp);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Functor implementation for recursive sorting with only Shift overridden
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned ii = 0; ii < bin_count - 1; ++ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
-- }
--
-- //Top-level sorting call for integers
-- template <class RandomAccessIter>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, *first >> 0, *first);
-- }
--
-- //integer_sort with functors
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift, compare comp) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //integer_sort with right_shift functor
-- template <class RandomAccessIter, class right_shift>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- //------------------------------------------------------ float_sort source --------------------------------------
-- //Casts a RandomAccessIter to the specified data type
-- template<class cast_type, class RandomAccessIter>
-- inline cast_type
-- cast_float_iter(const RandomAccessIter & floatiter)
-- {
-- cast_type result;
-- std::memcpy(&result, &(*floatiter), sizeof(cast_type));
-- return result;
-- }
--
-- //Casts a data element to the specified datinner_float_a type
-- template<class data_type, class cast_type>
-- inline cast_type
-- mem_cast(const data_type & data)
-- {
-- cast_type result;
-- std::memcpy(&result, &data, sizeof(cast_type));
-- return result;
-- }
--
-- namespace detail {
-- template <class RandomAccessIter, class div_type, class right_shift>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift)
-- {
-- min = max = shift(*current, 0);
-- while(++current < last) {
-- div_type value = shift(*current, 0);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Specialized swap loops for floating-point casting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min);
-- }
--
-- template <class RandomAccessIter, class cast_type>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min)
-- {
-- min = max = cast_float_iter<cast_type, RandomAccessIter>(current);
-- while(++current < last) {
-- cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Special-case sorting of positive floats with casting instead of a right_shift
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii], comp);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Casting special-case for floating-point sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min);
-- }
--
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- template <class RandomAccessIter, class cast_type, class data_type>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
-- }
--
-- //float_sort with casting
-- //The cast_type must be equal in size to the data type, and must be a signed integer
-- template <class RandomAccessIter, class cast_type>
-- inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, cVal, *first);
-- }
--
-- //float_sort with casting to an int
-- //Only use this with IEEE floating-point numbers
-- template <class RandomAccessIter>
-- inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last)
-- {
-- int cVal = 0;
-- float_sort_cast(first, last, cVal);
-- }
--
-- //float_sort with functors
-- template <class RandomAccessIter, class right_shift>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //------------------------------------------------- string_sort source ---------------------------------------------
-- namespace detail {
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter, class get_char, class get_length>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_lessthan {
-- offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() < y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_greaterthan {
-- offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() > y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class get_char, class get_length>
-- struct offset_char_lessthan {
-- offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(length(x), length(y));
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(getchar(x, u) < getchar(y, u))
-- return true;
-- else if(getchar(y, u) < getchar(x, u))
-- return false;
-- }
-- return length(x) < length(y);
-- }
-- unsigned fchar_offset;
-- get_char getchar;
-- get_length length;
-- };
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while((*first).size() <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;(*finish).size() <= char_offset; --finish) { }
-- ++finish;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, finish, char_offset);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while((*curr).size() <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while((*(--last)).size() <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(curr, last, char_offset);
-- RandomAccessIter * target_bin;
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned ii = 0; ii < last_bin; ++ii) {
-- local_bin = bins + ii;
-- nextbinstart += bin_sizes[ii + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*curr) <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while(length(*(--last)) <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, last, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - getchar((*current), char_offset)]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = end_bin - getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = end_bin - getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class unsignedchar_type>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- unsigned char unused = '\0';
-- string_sort(first, last, unused);
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class compare, class unsignedchar_type>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::reverse_string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp)
-- {
-- unsigned char unused = '\0';
-- reverse_string_sort(first, last, comp, unused);
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*(--last))) {
-- //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order
-- if(first == last)
-- return;
-- }
-- //making last just after the end of the non-empty part of the array
-- ++last;
-- detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--}
--
--#endif
-+//Templated spread_sort library -+ -+// Copyright Steven J. Ross 2001 - 2009. -+// Distributed under the Boost Software License, Version 1.0. -+// (See accompanying file LICENSE_1_0.txt or copy at -+// http://www.boost.org/LICENSE_1_0.txt) -+ -+// See http://www.boost.org/ for updates, documentation, and revision history. -+ -+/* -+Some improvements suggested by: -+Phil Endecott and Frank Gennari -+Cygwin fix provided by: -+Scott McMurray -+*/ -+ -+#ifndef BOOST_SPREAD_SORT_H -+#define BOOST_SPREAD_SORT_H -+#include <algorithm> -+#include <cstring> -+#include <vector> -+#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp" -+ -+#ifdef __FreeBSD__ -+# include <osreldate.h> -+# if __FreeBSD_version < 900506 -+# define getchar boost_getchar -+# endif -+#endif -+ -+namespace boost { -+ namespace detail { -+ //This only works on unsigned data types -+ template <typename T> -+ inline unsigned -+ rough_log_2_size(const T& input) -+ { -+ unsigned result = 0; -+ //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance -+ while((input >> result) && (result < (8*sizeof(T)))) ++result; -+ return result; -+ } -+ -+ //Gets the maximum size which we'll call spread_sort on to control worst-case performance -+ //Maintains both a minimum size to recurse and a check of distribution size versus count -+ //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead -+ inline size_t -+ get_max_count(unsigned log_range, size_t count) -+ { -+ unsigned divisor = rough_log_2_size(count); -+ //Making sure the divisor is positive -+ if(divisor > LOG_MEAN_BIN_SIZE) -+ divisor -= LOG_MEAN_BIN_SIZE; -+ else -+ divisor = 1; -+ unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor); -+ //Don't try to bitshift more than the size of an element -+ if((8*sizeof(size_t)) <= relative_width) -+ relative_width = (8*sizeof(size_t)) - 1; -+ return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ? -+ (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width); -+ } -+ -+ //Find the minimum and maximum using < -+ template <class RandomAccessIter> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min) -+ { -+ min = max = current; -+ //Start from the second item, as max and min are initialized to the first -+ while(++current < last) { -+ if(*max < *current) -+ max = current; -+ else if(*current < *min) -+ min = current; -+ } -+ } -+ -+ //Uses a user-defined comparison operator to find minimum and maximum -+ template <class RandomAccessIter, class compare> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp) -+ { -+ min = max = current; -+ while(++current < last) { -+ if(comp(*max, *current)) -+ max = current; -+ else if(comp(*current, *min)) -+ min = current; -+ } -+ } -+ -+ //Gets a non-negative right bit shift to operate as a logarithmic divisor -+ inline int -+ get_log_divisor(size_t count, unsigned log_range) -+ { -+ int log_divisor; -+ //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so -+ if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS) -+ log_divisor = 0; -+ else { -+ //otherwise divide the data into an optimized number of pieces -+ log_divisor += LOG_MEAN_BIN_SIZE; -+ if(log_divisor < 0) -+ log_divisor = 0; -+ //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically -+ if((log_range - log_divisor) > MAX_SPLITS) -+ log_divisor = log_range - MAX_SPLITS; -+ } -+ return log_divisor; -+ } -+ -+ template <class RandomAccessIter> -+ inline RandomAccessIter * -+ size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count) -+ { -+ //Assure space for the size of each bin, followed by initializing sizes -+ if(bin_count > bin_sizes.size()) -+ bin_sizes.resize(bin_count); -+ for(size_t u = 0; u < bin_count; u++) -+ bin_sizes[u] = 0; -+ //Make sure there is space for the bins -+ cache_end = cache_offset + bin_count; -+ if(cache_end > bin_cache.size()) -+ bin_cache.resize(cache_end); -+ return &(bin_cache[cache_offset]); -+ } -+ -+ //Implementation for recursive integer sorting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data -+ //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min); -+ //max and min will be the same (the first item) iff all values are equivalent -+ if(max == min) -+ return; -+ RandomAccessIter * target_bin; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0))); -+ div_type div_min = *min >> log_divisor; -+ div_type div_max = *max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(*(current++) >> log_divisor) - div_min]++; -+ //Assign the bin positions -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ //This dominates runtime, mostly in the swap and bin lookups -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) { -+ RandomAccessIter * local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + ((*current >> log_divisor) - div_min)) { -+ //3-way swap; this is about 1% faster than a 2-way swap with integers -+ //The main advantage is less copies are involved per item put in the correct place -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min); -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing; log_divisor is the remaining range -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Generic bitshift-based 3-way swapping code -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift -+ , const unsigned log_divisor, const div_type div_min) -+ { -+ RandomAccessIter * local_bin = bins + ii; -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + (shift(*current, log_divisor) - div_min)) { -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min); -+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ //Note: we could increment current once the swap is done in this case, but that seems to impair performance -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ -+ //Standard swapping wrapper for ascending values -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift -+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) -+ { -+ nextbinstart += bin_sizes[ii]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min); -+ } -+ -+ //Functor implementation for recursive sorting -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min, comp); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); -+ div_type div_min = shift(*min, log_divisor); -+ div_type div_max = shift(*max, log_divisor); -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ //Functor implementation for recursive sorting with only Shift overridden -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); -+ div_type div_min = shift(*min, log_divisor); -+ div_type div_max = shift(*max, log_divisor); -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned ii = 0; ii < bin_count - 1; ++ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); -+ } -+ } -+ -+ //Top-level sorting call for integers -+ template <class RandomAccessIter> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::spread_sort(first, last, *first >> 0, *first); -+ } -+ -+ //integer_sort with functors -+ template <class RandomAccessIter, class right_shift, class compare> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last, -+ right_shift shift, compare comp) { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp); -+ } -+ -+ //integer_sort with right_shift functor -+ template <class RandomAccessIter, class right_shift> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last, -+ right_shift shift) { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::spread_sort(first, last, shift(*first, 0), *first, shift); -+ } -+ -+ //------------------------------------------------------ float_sort source -------------------------------------- -+ //Casts a RandomAccessIter to the specified data type -+ template<class cast_type, class RandomAccessIter> -+ inline cast_type -+ cast_float_iter(const RandomAccessIter & floatiter) -+ { -+ cast_type result; -+ std::memcpy(&result, &(*floatiter), sizeof(cast_type)); -+ return result; -+ } -+ -+ //Casts a data element to the specified datinner_float_a type -+ template<class data_type, class cast_type> -+ inline cast_type -+ mem_cast(const data_type & data) -+ { -+ cast_type result; -+ std::memcpy(&result, &data, sizeof(cast_type)); -+ return result; -+ } -+ -+ namespace detail { -+ template <class RandomAccessIter, class div_type, class right_shift> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift) -+ { -+ min = max = shift(*current, 0); -+ while(++current < last) { -+ div_type value = shift(*current, 0); -+ if(max < value) -+ max = value; -+ else if(value < min) -+ min = value; -+ } -+ } -+ -+ //Specialized swap loops for floating-point casting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii -+ , const unsigned log_divisor, const div_type div_min) -+ { -+ RandomAccessIter * local_bin = bins + ii; -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) { -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min); -+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii -+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) -+ { -+ nextbinstart += bin_sizes[ii]; -+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min); -+ } -+ -+ template <class RandomAccessIter, class cast_type> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min) -+ { -+ min = max = cast_float_iter<cast_type, RandomAccessIter>(current); -+ while(++current < last) { -+ cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current); -+ if(max < value) -+ max = value; -+ else if(value < min) -+ min = value; -+ } -+ } -+ -+ //Special-case sorting of positive floats with casting instead of a right_shift -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) -+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorting negative_ float_s -+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorting negative_ float_s -+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii], comp); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ //Casting special-case for floating-point sorting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min); -+ } -+ -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Functor implementation for recursive sorting -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); -+ } -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); -+ } -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ template <class RandomAccessIter, class cast_type, class data_type> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp); -+ } -+ } -+ -+ //float_sort with casting -+ //The cast_type must be equal in size to the data type, and must be a signed integer -+ template <class RandomAccessIter, class cast_type> -+ inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::float_Sort(first, last, cVal, *first); -+ } -+ -+ //float_sort with casting to an int -+ //Only use this with IEEE floating-point numbers -+ template <class RandomAccessIter> -+ inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last) -+ { -+ int cVal = 0; -+ float_sort_cast(first, last, cVal); -+ } -+ -+ //float_sort with functors -+ template <class RandomAccessIter, class right_shift> -+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::float_Sort(first, last, shift(*first, 0), *first, shift); -+ } -+ -+ template <class RandomAccessIter, class right_shift, class compare> -+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp); -+ } -+ -+ //------------------------------------------------- string_sort source --------------------------------------------- -+ namespace detail { -+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. -+ template<class RandomAccessIter> -+ inline void -+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset) -+ { -+ unsigned nextOffset = char_offset; -+ bool done = false; -+ while(!done) { -+ RandomAccessIter curr = first; -+ do { -+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character -+ if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) { -+ done = true; -+ break; -+ } -+ } while(++curr != finish); -+ if(!done) -+ ++nextOffset; -+ } -+ char_offset = nextOffset; -+ } -+ -+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. -+ template<class RandomAccessIter, class get_char, class get_length> -+ inline void -+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length) -+ { -+ unsigned nextOffset = char_offset; -+ bool done = false; -+ while(!done) { -+ RandomAccessIter curr = first; -+ do { -+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character -+ if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) { -+ done = true; -+ break; -+ } -+ } while(++curr != finish); -+ if(!done) -+ ++nextOffset; -+ } -+ char_offset = nextOffset; -+ } -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class unsignedchar_type> -+ struct offset_lessthan { -+ offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(x.size(), y.size()); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u])) -+ return true; -+ else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u])) -+ return false; -+ } -+ return x.size() < y.size(); -+ } -+ unsigned fchar_offset; -+ }; -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class unsignedchar_type> -+ struct offset_greaterthan { -+ offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(x.size(), y.size()); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u])) -+ return true; -+ else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u])) -+ return false; -+ } -+ return x.size() > y.size(); -+ } -+ unsigned fchar_offset; -+ }; -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class get_char, class get_length> -+ struct offset_char_lessthan { -+ offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(length(x), length(y)); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(getchar(x, u) < getchar(y, u)) -+ return true; -+ else if(getchar(y, u) < getchar(x, u)) -+ return false; -+ } -+ return length(x) < length(y); -+ } -+ unsigned fchar_offset; -+ get_char getchar; -+ get_length length; -+ }; -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while((*first).size() <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;(*finish).size() <= char_offset; --finish) { } -+ ++finish; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(first, finish, char_offset); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if((*current).size() <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while((*current).size() > char_offset) { -+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; -+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset])) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1)); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorts strings in reverse order, with empties at the end -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ RandomAccessIter curr = first; -+ //Iterate to the end of the empties. If all empty, return -+ while((*curr).size() <= char_offset) { -+ if(++curr == last) -+ return; -+ } -+ //Getting the last non-empty -+ while((*(--last)).size() <= char_offset) { } -+ ++last; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(curr, last, char_offset); -+ RandomAccessIter * target_bin; -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ const unsigned max_bin = bin_count - 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); -+ RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if((*current).size() <= char_offset) { -+ bin_sizes[bin_count]++; -+ } -+ else -+ bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = last; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); -+ RandomAccessIter lastFull = *local_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while((*current).size() > char_offset) { -+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ nextbinstart = first; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = max_bin; -+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; -+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset])) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = lastFull; -+ //Recursing -+ RandomAccessIter lastPos = first; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1)); -+ else -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*first) <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;length(*finish) <= char_offset; --finish) { } -+ ++finish; -+ update_offset(first, finish, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[getchar((*current), char_offset) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = bins + getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned ii = 0; ii < last_bin; ++ii) { -+ local_bin = bins + ii; -+ nextbinstart += bin_sizes[ii + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = bins + getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1)); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length); -+ } -+ } -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*first) <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;length(*finish) <= char_offset; --finish) { } -+ ++finish; -+ update_offset(first, finish, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[getchar((*current), char_offset) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = bins + getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = bins + getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos -+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Sorts strings in reverse order, with empties at the end -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> -+ inline void -+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ RandomAccessIter curr = first; -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*curr) <= char_offset) { -+ if(++curr == last) -+ return; -+ } -+ //Getting the last non-empty -+ while(length(*(--last)) <= char_offset) { } -+ ++last; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(first, last, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ const unsigned max_bin = bin_count - 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); -+ RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[bin_count]++; -+ } -+ else -+ bin_sizes[max_bin - getchar((*current), char_offset)]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = last; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); -+ RandomAccessIter lastFull = *local_bin; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = end_bin - getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ nextbinstart = first; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = max_bin; -+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = end_bin - getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = lastFull; -+ //Recursing -+ RandomAccessIter lastPos = first; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos -+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Allows character-type overloads -+ template <class RandomAccessIter, class unsignedchar_type> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::string_sort(first, last, *first, unused); -+ } -+ -+ //Top-level sorting call; wraps using default of unsigned char -+ template <class RandomAccessIter> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last) -+ { -+ unsigned char unused = '\0'; -+ string_sort(first, last, unused); -+ } -+ -+ //Allows character-type overloads -+ template <class RandomAccessIter, class compare, class unsignedchar_type> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::reverse_string_sort(first, last, *first, unused); -+ } -+ -+ //Top-level sorting call; wraps using default of unsigned char -+ template <class RandomAccessIter, class compare> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp) -+ { -+ unsigned char unused = '\0'; -+ reverse_string_sort(first, last, comp, unused); -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*first)) { -+ if(++first == last) -+ return; -+ } -+ detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0)); -+ } -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length, class compare> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*first)) { -+ if(++first == last) -+ return; -+ } -+ detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); -+ } -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length, class compare> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*(--last))) { -+ //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order -+ if(first == last) -+ return; -+ } -+ //making last just after the end of the non-empty part of the array -+ ++last; -+ detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); -+ } -+ } -+} -+ -+#endif +@@ -21,6 +21,13 @@ Scott McMurray
+ #include <vector>
+ #include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
+
++#ifdef __FreeBSD__
++# include <osreldate.h>
++# if __FreeBSD_version < 900506
++# define getchar boost_getchar
++# endif
++#endif
++
+ namespace boost {
+ namespace detail {
+ //This only works on unsigned data types
diff --git a/www/seamonkey/patches/patch-mozilla_memory_jemalloc_Makefile.in b/www/seamonkey/patches/patch-mozilla_memory_jemalloc_Makefile.in new file mode 100644 index 00000000000..5d1074999e7 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_memory_jemalloc_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-mozilla_memory_jemalloc_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/memory/jemalloc/Makefile.in.orig 2014-03-19 01:42:09.000000000 +0000 ++++ mozilla/memory/jemalloc/Makefile.in +@@ -21,3 +21,7 @@ endif + ifdef GNU_CC + CFLAGS += -std=gnu99 + endif ++ ++# XXX startup crash workaround for gcc47 on amd64 ++jemalloc.$(OBJ_SUFFIX): OS_CFLAGS := $(filter-out -O3 -Ofast,$(OS_CFLAGS)) ++jemalloc.$(OBJ_SUFFIX): MOZ_OPTIMIZE_FLAGS= diff --git a/www/seamonkey/patches/patch-mozilla_netwerk_dns_Makefile.in b/www/seamonkey/patches/patch-mozilla_netwerk_dns_Makefile.in new file mode 100644 index 00000000000..f5f9c9a84a2 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_netwerk_dns_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-mozilla_netwerk_dns_Makefile.in,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/netwerk/dns/Makefile.in.orig 2014-03-19 01:42:11.000000000 +0000 ++++ mozilla/netwerk/dns/Makefile.in +@@ -9,3 +9,7 @@ include $(topsrcdir)/config/rules.mk + # for effective TLD data. + etld_data.inc: $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat + $(PYTHON) $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat > etld_data.inc ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++nsIDNService.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif diff --git a/www/seamonkey/patches/patch-mozilla_netwerk_wifi_moz.build b/www/seamonkey/patches/patch-mozilla_netwerk_wifi_moz.build index d40019623bc..7a6de27cde6 100644 --- a/www/seamonkey/patches/patch-mozilla_netwerk_wifi_moz.build +++ b/www/seamonkey/patches/patch-mozilla_netwerk_wifi_moz.build @@ -1,15 +1,15 @@ -$NetBSD: patch-mozilla_netwerk_wifi_moz.build,v 1.3 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_netwerk_wifi_moz.build,v 1.4 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/netwerk/wifi/moz.build.orig 2013-12-11 04:29:10.000000000 +0000 +--- mozilla/netwerk/wifi/moz.build.orig 2014-03-19 01:42:12.000000000 +0000 +++ mozilla/netwerk/wifi/moz.build -@@ -38,6 +38,10 @@ if CONFIG['OS_ARCH'] == 'Darwin': - CMMSRCS += [ +@@ -35,6 +35,10 @@ if CONFIG['OS_ARCH'] == 'Darwin': + UNIFIED_SOURCES += [ 'osx_corewlan.mm', ] +elif CONFIG['OS_ARCH'] == 'FreeBSD': -+ CPP_SOURCES += [ ++ UNIFIED_SOURCES += [ + 'nsWifiScannerFreeBSD.cpp', + ] elif CONFIG['OS_ARCH'] == 'WINNT': - CPP_SOURCES += [ + UNIFIED_SOURCES += [ 'nsWifiScannerWin.cpp', diff --git a/www/seamonkey/patches/patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp b/www/seamonkey/patches/patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp index 88979dae9e8..5eb0d5befab 100644 --- a/www/seamonkey/patches/patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp +++ b/www/seamonkey/patches/patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp @@ -1,8 +1,8 @@ -$NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.1 2013/09/28 14:37:05 ryoon Exp $ +$NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2013-09-28 01:07:16.000000000 +0000 +--- mozilla/netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2014-03-29 04:22:17.000000000 +0000 +++ mozilla/netwerk/wifi/nsWifiScannerFreeBSD.cpp -@@ -0,0 +1,172 @@ +@@ -0,0 +1,167 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -31,43 +31,39 @@ $NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.1 2013/09/28 14 +static nsresult +FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints) +{ -+ bool res = false; -+ char *dupn = NULL; -+ struct ifaddrs *ifal, *ifa; -+ unsigned len; -+ + // get list of interfaces -+ if (getifaddrs(&ifal) < 0) ++ struct ifaddrs *ifal; ++ if (getifaddrs(&ifal) < 0) { + return NS_ERROR_FAILURE; ++ } + + accessPoints.Clear(); + + // loop through the interfaces ++ nsresult rv = NS_ERROR_FAILURE; ++ struct ifaddrs *ifa; + for (ifa = ifal; ifa; ifa = ifa->ifa_next) { -+ int s; -+ struct ifreq ifr; -+ struct ifmediareq ifmr; -+ struct ieee80211req i802r; -+ char iscanbuf[32*1024], *vsr; -+ -+ memset(&ifr, 0, sizeof(ifr)); -+ -+ // list can contain duplicates, so ignore those -+ if (dupn != NULL && strcmp(dupn, ifa->ifa_name) == 0) ++ // limit to one interface per address ++ if (ifa->ifa_addr->sa_family != AF_LINK) { + continue; -+ dupn = ifa->ifa_name; ++ } + + // store interface name in socket structure ++ struct ifreq ifr; ++ memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); + ifr.ifr_addr.sa_family = AF_LOCAL; + + // open socket to interface -+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) ++ int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); ++ if (s < 0) { + continue; ++ } + + // clear interface media structure -+ (void) memset(&ifmr, 0, sizeof(ifmr)); -+ (void) strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name)); ++ struct ifmediareq ifmr; ++ memset(&ifmr, 0, sizeof(ifmr)); ++ strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name)); + + // get interface media information + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { @@ -82,8 +78,10 @@ $NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.1 2013/09/28 14 + } + + // perform WiFi scan -+ (void) memset(&i802r, 0, sizeof(i802r)); -+ (void) strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name)); ++ struct ieee80211req i802r; ++ char iscanbuf[32*1024]; ++ memset(&i802r, 0, sizeof(i802r)); ++ strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name)); + i802r.i_type = IEEE80211_IOC_SCAN_RESULTS; + i802r.i_data = iscanbuf; + i802r.i_len = sizeof(iscanbuf); @@ -96,36 +94,33 @@ $NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.1 2013/09/28 14 + close(s); + + // loop through WiFi networks and build geoloc-lookup structure -+ vsr = (char *) i802r.i_data; -+ len = i802r.i_len; ++ char *vsr = (char *) i802r.i_data; ++ unsigned len = i802r.i_len; + while (len >= sizeof(struct ieee80211req_scan_result)) { -+ struct ieee80211req_scan_result *isr; -+ char *id; -+ int idlen; -+ char ssid[IEEE80211_NWID_LEN+1]; -+ nsWifiAccessPoint *ap; -+ -+ isr = (struct ieee80211req_scan_result *) vsr; ++ struct ieee80211req_scan_result *isr = ++ (struct ieee80211req_scan_result *) vsr; + + // determine size of this entry ++ char *id; ++ int idlen; + if (isr->isr_meshid_len) { + id = vsr + isr->isr_ie_off + isr->isr_ssid_len; + idlen = isr->isr_meshid_len; -+ } -+ else { ++ } else { + id = vsr + isr->isr_ie_off; + idlen = isr->isr_ssid_len; + } + + // copy network data ++ char ssid[IEEE80211_NWID_LEN+1]; + strncpy(ssid, id, idlen); + ssid[idlen] = '\0'; -+ ap = new nsWifiAccessPoint(); ++ nsWifiAccessPoint *ap = new nsWifiAccessPoint(); + ap->setSSID(ssid, strlen(ssid)); + ap->setMac(isr->isr_bssid); + ap->setSignal(isr->isr_rssi); + accessPoints.AppendObject(ap); -+ res = true; ++ rv = NS_OK; + + // log the data + LOG(( "FreeBSD access point: " @@ -143,7 +138,7 @@ $NetBSD: patch-mozilla_netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.1 2013/09/28 14 + + freeifaddrs(ifal); + -+ return res ? NS_OK : NS_ERROR_FAILURE; ++ return rv; +} + +nsresult diff --git a/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__allthreads.jsm b/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__allthreads.jsm new file mode 100644 index 00000000000..cfe71f3045d --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__allthreads.jsm @@ -0,0 +1,13 @@ +$NetBSD: patch-mozilla_toolkit_components_osfile_modules_osfile__unix__allthreads.jsm,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/toolkit/components/osfile/modules/osfile_unix_allthreads.jsm.orig 2014-03-19 01:42:15.000000000 +0000 ++++ mozilla/toolkit/components/osfile/modules/osfile_unix_allthreads.jsm +@@ -41,7 +41,7 @@ let Const = SharedAll.Constants.libc; + // Open libc + let libc; + let libc_candidates = [ "libSystem.B.dylib", +- "libc.so.6", ++ "libc.so.7", + "libc.so" ]; + for (let i = 0; i < libc_candidates.length; ++i) { + try { diff --git a/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm b/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm index f598df2a43a..fb2e0f207b3 100644 --- a/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm +++ b/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm @@ -1,71 +1,28 @@ -$NetBSD: patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.2 2013/11/13 14:23:02 ryoon Exp $ +$NetBSD: patch-mozilla_toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.3 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2013-10-29 01:21:11.000000000 +0000 +--- mozilla/toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2014-03-19 01:42:15.000000000 +0000 +++ mozilla/toolkit/components/osfile/modules/osfile_unix_back.jsm -@@ -170,7 +170,7 @@ - } - - stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_SIZE, -- "st_size", Types.size_t.implementation); -+ "st_size", Types.off_t.implementation); - Types.stat = stat.getType(); - } - -@@ -397,10 +397,17 @@ - /*oflags*/Types.int, - /*mode*/ Types.int); - -+ if (OS.Constants.Sys.Name == "NetBSD") { -+ UnixFile.opendir = -+ declareFFI("__opendir30", ctypes.default_abi, -+ /*return*/ Types.null_or_DIR_ptr, -+ /*path*/ Types.path); -+ } else { - UnixFile.opendir = - declareFFI("opendir", ctypes.default_abi, - /*return*/ Types.null_or_DIR_ptr, - /*path*/ Types.path); -+ } - - UnixFile.pread = - declareFFI("pread", ctypes.default_abi, -@@ -434,6 +441,11 @@ - declareFFI("readdir$INODE64", ctypes.default_abi, - /*return*/Types.null_or_dirent_ptr, - /*dir*/ Types.DIR.in_ptr); // For MacOS X -+ } else if (OS.Constants.Sys.Name == "NetBSD") { -+ UnixFile.readdir = -+ declareFFI("__readdir30", ctypes.default_abi, -+ /*return*/Types.null_or_dirent_ptr, -+ /*dir*/ Types.DIR.in_ptr); - } else { - UnixFile.readdir = - declareFFI("readdir", ctypes.default_abi, -@@ -553,6 +565,27 @@ - UnixFile.fstat = function stat(fd, buf) { - return fxstat(ver, fd, buf); +@@ -558,18 +558,19 @@ + return Stat.fxstat(ver, fd, buf); }; -+ } else if (OS.Constants.Sys.Name == "NetBSD") { + } else if (OS.Constants.Sys.Name == "NetBSD") { +- // NetBSD 5.0 and newer +- declareLazyFFI(SysFile, "stat", libc, "__stat50", ctypes.default_abi, + // NetBSD 5.0 uses *30, and netbsd-6 uses *50 + let v = OS.Constants.libc.OSFILE_SIZEOF_TIME_T < 8 ? "30" : "50"; -+ UnixFile.stat = -+ declareFFI("__stat"+v, ctypes.default_abi, -+ /*return*/ Types.negativeone_or_nothing, -+ /*path*/ Types.path, -+ /*buf*/ Types.stat.out_ptr -+ ); -+ UnixFile.lstat = -+ declareFFI("__lstat"+v, ctypes.default_abi, -+ /*return*/ Types.negativeone_or_nothing, -+ /*path*/ Types.path, -+ /*buf*/ Types.stat.out_ptr -+ ); -+ UnixFile.fstat = -+ declareFFI("__fstat"+v, ctypes.default_abi, -+ /*return*/ Types.negativeone_or_nothing, -+ /*fd*/ Types.fd, -+ /*buf*/ Types.stat.out_ptr -+ ); - } else { - // Mac OS X 32-bits, other Unix - UnixFile.stat = ++ declareLazyFFI(SysFile, "stat", libc, "__stat"+v, ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); +- declareLazyFFI(SysFile, "lstat", libc, "__lstat50", ctypes.default_abi, ++ declareLazyFFI(SysFile, "lstat", libc, "__lstat"+v, ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); +- declareLazyFFI(SysFile, "fstat", libc, "__fstat50", ctypes.default_abi, ++ declareLazyFFI(SysFile, "fstat", libc, "__fstat"+v, ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*fd*/ Type.fd, + /*buf*/ Type.stat.out_ptr diff --git a/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__front.jsm b/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__front.jsm deleted file mode 100644 index 051a5a65a08..00000000000 --- a/www/seamonkey/patches/patch-mozilla_toolkit_components_osfile_modules_osfile__unix__front.jsm +++ /dev/null @@ -1,13 +0,0 @@ -$NetBSD: patch-mozilla_toolkit_components_osfile_modules_osfile__unix__front.jsm,v 1.1 2013/11/08 12:55:52 ryoon Exp $ - ---- mozilla/toolkit/components/osfile/modules/osfile_unix_front.jsm.orig 2013-10-29 01:21:11.000000000 +0000 -+++ mozilla/toolkit/components/osfile/modules/osfile_unix_front.jsm -@@ -734,7 +734,7 @@ - File.Info = function Info(stat) { - let isDir = (stat.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFDIR; - let isSymLink = (stat.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFLNK; -- let size = exports.OS.Shared.Type.size_t.importFromC(stat.st_size); -+ let size = exports.OS.Shared.Type.off_t.importFromC(stat.st_size); - - let lastAccessDate = new Date(stat.st_atime * 1000); - let lastModificationDate = new Date(stat.st_mtime * 1000); diff --git a/www/seamonkey/patches/patch-mozilla_toolkit_library_Makefile.in b/www/seamonkey/patches/patch-mozilla_toolkit_library_Makefile.in index 2619f02271e..d66c4fef1f5 100644 --- a/www/seamonkey/patches/patch-mozilla_toolkit_library_Makefile.in +++ b/www/seamonkey/patches/patch-mozilla_toolkit_library_Makefile.in @@ -1,23 +1,46 @@ -$NetBSD: patch-mozilla_toolkit_library_Makefile.in,v 1.2 2013/12/26 13:17:37 ryoon Exp $ +$NetBSD: patch-mozilla_toolkit_library_Makefile.in,v 1.3 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/toolkit/library/Makefile.in.orig 2013-12-11 04:29:15.000000000 +0000 +--- mozilla/toolkit/library/Makefile.in.orig 2014-03-19 01:42:16.000000000 +0000 +++ mozilla/toolkit/library/Makefile.in -@@ -399,6 +399,7 @@ endif - EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib) +@@ -164,6 +164,18 @@ ifdef MOZ_NATIVE_HUNSPELL + EXTRA_DSO_LDOPTS += $(MOZ_HUNSPELL_LIBS) + endif - ifdef MOZ_WEBRTC -+EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS) - ifdef MOZ_PEERCONNECTION - COMPONENT_LIBS += peerconnection ++ifdef MOZ_NATIVE_OGG ++EXTRA_DSO_LDOPTS += $(MOZ_OGG_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_VORBIS ++EXTRA_DSO_LDOPTS += $(MOZ_VORBIS_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_OPUS ++EXTRA_DSO_LDOPTS += $(MOZ_OPUS_LIBS) ++endif ++ + ifdef MOZ_NATIVE_LIBEVENT + EXTRA_DSO_LDOPTS += $(MOZ_LIBEVENT_LIBS) endif -@@ -541,6 +542,10 @@ OS_LIBS += $(call EXPAND_LIBNAME,kvm) - EXTRA_DSO_LDOPTS += -Wl,--warn-unresolved-symbols +@@ -176,6 +188,14 @@ ifndef MOZ_TREE_PIXMAN + EXTRA_DSO_LDOPTS += $(MOZ_PIXMAN_LIBS) endif -+ifeq ($(OS_ARCH),FreeBSD) -+OS_LIBS += $(call EXPAND_LIBNAME,util) ++ifdef MOZ_NATIVE_GRAPHITE2 ++EXTRA_DSO_LDOPTS += $(MOZ_GRAPHITE2_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++EXTRA_DSO_LDOPTS += $(MOZ_HARFBUZZ_LIBS) +endif + - ifeq ($(OS_ARCH),WINNT) - OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 version winspool comdlg32 imm32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg iphlpapi uxtheme setupapi secur32 sensorsapi portabledeviceguids windowscodecs wininet) - ifdef ACCESSIBILITY + ifdef MOZ_DMD + EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,dmd,$(DIST)/lib) + endif +@@ -183,6 +203,7 @@ endif + EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib) + + ifdef MOZ_WEBRTC ++EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS) + ifdef MOZ_WEBRTC_SIGNALING + SHARED_LIBRARY_LIBS += \ + $(DEPTH)/media/webrtc/signaling/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \ diff --git a/www/seamonkey/patches/patch-mozilla_toolkit_xre_Makefile.in b/www/seamonkey/patches/patch-mozilla_toolkit_xre_Makefile.in deleted file mode 100644 index 6a5bb68637d..00000000000 --- a/www/seamonkey/patches/patch-mozilla_toolkit_xre_Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -$NetBSD: patch-mozilla_toolkit_xre_Makefile.in,v 1.1 2013/09/28 14:37:05 ryoon Exp $ - ---- mozilla/toolkit/xre/Makefile.in.orig 2013-09-16 18:27:01.000000000 +0000 -+++ mozilla/toolkit/xre/Makefile.in -@@ -216,5 +216,3 @@ GARBAGE += platform.ini - libs:: platform.ini - $(INSTALL) $^ $(DIST)/bin - --install:: -- $(INSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir) diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryInfoDumper.cpp b/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryInfoDumper.cpp deleted file mode 100644 index 78f8da3b063..00000000000 --- a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryInfoDumper.cpp +++ /dev/null @@ -1,31 +0,0 @@ -$NetBSD: patch-mozilla_xpcom_base_nsMemoryInfoDumper.cpp,v 1.1 2013/12/26 13:17:37 ryoon Exp $ - ---- mozilla/xpcom/base/nsMemoryInfoDumper.cpp.orig 2013-12-11 04:29:24.000000000 +0000 -+++ mozilla/xpcom/base/nsMemoryInfoDumper.cpp -@@ -30,7 +30,7 @@ - #include <unistd.h> - #endif - --#ifdef XP_LINUX -+#if defined(XP_LINUX) || defined(__FreeBSD__) - #include <fcntl.h> - #include <sys/types.h> - #include <sys/stat.h> -@@ -109,7 +109,7 @@ private: - - } // anonymous namespace - --#ifdef XP_LINUX // { -+#if defined(XP_LINUX) || defined(__FreeBSD__) // { - namespace { - - /* -@@ -548,7 +548,7 @@ nsMemoryInfoDumper::~nsMemoryInfoDumper( - /* static */ void - nsMemoryInfoDumper::Initialize() - { --#ifdef XP_LINUX -+#if defined(XP_LINUX) || defined(__FreeBSD__) - SignalPipeWatcher::Create(); - FifoWatcher::MaybeCreate(); - #endif diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryReporterManager.cpp b/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryReporterManager.cpp deleted file mode 100644 index 0f49948598f..00000000000 --- a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsMemoryReporterManager.cpp +++ /dev/null @@ -1,106 +0,0 @@ -$NetBSD: patch-mozilla_xpcom_base_nsMemoryReporterManager.cpp,v 1.1 2013/12/26 13:17:37 ryoon Exp $ - ---- mozilla/xpcom/base/nsMemoryReporterManager.cpp.orig 2013-12-11 04:29:24.000000000 +0000 -+++ mozilla/xpcom/base/nsMemoryReporterManager.cpp -@@ -196,6 +196,43 @@ static nsresult GetResidentFast(int64_t* - return GetResident(aN); - } - -+#ifdef __FreeBSD__ -+#include <libutil.h> -+ -+static nsresult -+GetKinfoVmentrySelf(int64_t* prss) -+{ -+ int cnt; -+ struct kinfo_vmentry *vmmap, *kve; -+ if ((vmmap = kinfo_getvmmap(getpid(), &cnt)) == NULL) -+ return NS_ERROR_FAILURE; -+ -+ if (prss) -+ *prss = 0; -+ -+ for (int i = 0; i < cnt; i++) { -+ kve = &vmmap[i]; -+ if (prss) -+ *prss += kve->kve_private_resident; -+ } -+ -+ free(vmmap); -+ return NS_OK; -+} -+ -+#define HAVE_PRIVATE_REPORTER -+static nsresult -+GetPrivate(int64_t* aN) -+{ -+ int64_t priv; -+ nsresult rv = GetKinfoVmentrySelf(&priv); -+ if (NS_SUCCEEDED(rv)) -+ *aN = priv * getpagesize(); -+ -+ return NS_OK; -+} -+#endif // FreeBSD -+ - #elif defined(SOLARIS) - - #include <procfs.h> -@@ -370,6 +407,24 @@ static nsresult GetResidentFast(int64_t* - } - - #define HAVE_PRIVATE_REPORTER -+static nsresult -+GetPrivate(int64_t* aN) -+{ -+ PROCESS_MEMORY_COUNTERS_EX pmcex; -+ pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX); -+ -+ if (!GetProcessMemoryInfo( -+ GetCurrentProcess(), -+ (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) { -+ return NS_ERROR_FAILURE; -+ } -+ -+ *aN = pmcex.PrivateUsage; -+ return NS_OK; -+} -+#endif // XP_<PLATFORM> -+ -+#ifdef HAVE_PRIVATE_REPORTER - class PrivateReporter MOZ_FINAL : public MemoryUniReporter - { - public: -@@ -382,21 +437,10 @@ public: - - NS_IMETHOD GetAmount(int64_t* aAmount) - { -- PROCESS_MEMORY_COUNTERS_EX pmcex; -- pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX); -- -- if (!GetProcessMemoryInfo( -- GetCurrentProcess(), -- (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) { -- return NS_ERROR_FAILURE; -- } -- -- *aAmount = pmcex.PrivateUsage; -- return NS_OK; -+ return GetPrivate(aAmount); - } - }; -- --#endif // XP_<PLATFORM> -+#endif - - #ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS - class VsizeReporter MOZ_FINAL : public MemoryUniReporter -@@ -780,7 +824,7 @@ nsMemoryReporterManager::Init() - RegisterReporter(new mozilla::dmd::DMDReporter); - #endif - --#if defined(XP_LINUX) -+#if defined(XP_LINUX) || defined(__FreeBSD__) - nsMemoryInfoDumper::Initialize(); - #endif - diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsStackWalk.cpp b/www/seamonkey/patches/patch-mozilla_xpcom_base_nsStackWalk.cpp index d659d8b1722..0a92de1b51a 100644 --- a/www/seamonkey/patches/patch-mozilla_xpcom_base_nsStackWalk.cpp +++ b/www/seamonkey/patches/patch-mozilla_xpcom_base_nsStackWalk.cpp @@ -1,8 +1,21 @@ -$NetBSD: patch-mozilla_xpcom_base_nsStackWalk.cpp,v 1.1 2013/08/11 03:18:46 ryoon Exp $ +$NetBSD: patch-mozilla_xpcom_base_nsStackWalk.cpp,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/xpcom/base/nsStackWalk.cpp.orig 2013-08-04 03:05:53.000000000 +0000 +--- mozilla/xpcom/base/nsStackWalk.cpp.orig 2014-03-19 01:42:18.000000000 +0000 +++ mozilla/xpcom/base/nsStackWalk.cpp -@@ -853,7 +853,7 @@ void DemangleSymbol(const char * aSymbol +@@ -23,6 +23,12 @@ struct CriticalAddress { + }; + static CriticalAddress gCriticalAddress; + ++// for _Unwind_Backtrace from libcxxrt or libunwind ++// cxxabi.h from libcxxrt implicitly includes unwind.h first ++#if defined(HAVE__UNWIND_BACKTRACE) && !defined(_GNU_SOURCE) ++#define _GNU_SOURCE ++#endif ++ + #if defined(HAVE_DLOPEN) || defined(XP_MACOSX) + #include <dlfcn.h> + #endif +@@ -874,7 +880,7 @@ void DemangleSymbol(const char * aSymbol } @@ -11,3 +24,13 @@ $NetBSD: patch-mozilla_xpcom_base_nsStackWalk.cpp,v 1.1 2013/08/11 03:18:46 ryoo /* * Stack walking code for Solaris courtesy of Bart Smaalder's "memtrak". +@@ -1223,9 +1229,6 @@ NS_StackWalk(NS_WalkStackCallback aCallb + #elif defined(HAVE__UNWIND_BACKTRACE) + + // libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0 +-#ifndef _GNU_SOURCE +-#define _GNU_SOURCE +-#endif + #include <unwind.h> + + struct unwind_info { diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_base_nscore.h b/www/seamonkey/patches/patch-mozilla_xpcom_base_nscore.h new file mode 100644 index 00000000000..3c6533ed784 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_xpcom_base_nscore.h @@ -0,0 +1,13 @@ +$NetBSD: patch-mozilla_xpcom_base_nscore.h,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/xpcom/base/nscore.h.orig 2014-03-19 01:42:18.000000000 +0000 ++++ mozilla/xpcom/base/nscore.h +@@ -110,7 +110,7 @@ + * NS_HIDDEN_(int) NS_FASTCALL func2(char *foo); + */ + +-#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2) ++#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2) && !(defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ == 0) + #define NS_FASTCALL __attribute__ ((regparm (3), stdcall)) + #define NS_CONSTRUCTOR_FASTCALL __attribute__ ((regparm (3), stdcall)) + #elif defined(XP_WIN) && !defined(_WIN64) diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_ds_moz.build b/www/seamonkey/patches/patch-mozilla_xpcom_ds_moz.build deleted file mode 100644 index 1f1b49cda2d..00000000000 --- a/www/seamonkey/patches/patch-mozilla_xpcom_ds_moz.build +++ /dev/null @@ -1,23 +0,0 @@ -$NetBSD: patch-mozilla_xpcom_ds_moz.build,v 1.3 2013/12/26 13:17:37 ryoon Exp $ - ---- mozilla/xpcom/ds/moz.build.orig 2013-12-11 04:29:24.000000000 +0000 -+++ mozilla/xpcom/ds/moz.build -@@ -90,7 +90,6 @@ CPP_SOURCES += [ - 'nsSupportsArrayEnumerator.cpp', - 'nsSupportsPrimitives.cpp', - 'nsVariant.cpp', -- 'TimeStamp.cpp', - ] - - if CONFIG['OS_ARCH'] == 'WINNT': -@@ -108,6 +107,10 @@ elif CONFIG['OS_ARCH'] == 'Darwin': - else: - error('No TimeStamp implementation on this platform. Build will not succeed') - -+CPP_SOURCES += [ -+ 'TimeStamp.cpp', -+] -+ - EXTRA_COMPONENTS += [ - 'nsINIProcessor.js', - 'nsINIProcessor.manifest', diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_io_nsLocalFileUnix.cpp b/www/seamonkey/patches/patch-mozilla_xpcom_io_nsLocalFileUnix.cpp new file mode 100644 index 00000000000..3fc32aa8526 --- /dev/null +++ b/www/seamonkey/patches/patch-mozilla_xpcom_io_nsLocalFileUnix.cpp @@ -0,0 +1,13 @@ +$NetBSD: patch-mozilla_xpcom_io_nsLocalFileUnix.cpp,v 1.1 2014/03/30 04:13:17 ryoon Exp $ + +--- mozilla/xpcom/io/nsLocalFileUnix.cpp.orig 2014-03-19 01:42:18.000000000 +0000 ++++ mozilla/xpcom/io/nsLocalFileUnix.cpp +@@ -382,7 +382,7 @@ nsLocalFile::OpenNSPRFileDesc(int32_t fl + PR_Delete(mPath.get()); + } + +-#if defined(LINUX) && !defined(ANDROID) ++#if defined(HAVE_POSIX_FADVISE) + if (flags & OS_READAHEAD) { + posix_fadvise(PR_FileDesc2NativeHandle(*_retval), 0, 0, + POSIX_FADV_SEQUENTIAL); diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build index 77ec591f05e..4070c06ea64 100644 --- a/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build +++ b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build @@ -1,15 +1,15 @@ -$NetBSD: patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.1 2013/09/28 14:37:05 ryoon Exp $ +$NetBSD: patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.2 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2013-09-16 18:27:02.000000000 +0000 +--- mozilla/xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2014-03-19 01:42:18.000000000 +0000 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/moz.build @@ -19,14 +19,14 @@ if CONFIG['OS_ARCH'] == 'Darwin': - 'xptcstubs_gcc_x86_unix.cpp', - ] + if '86' in CONFIG['OS_TEST'] and CONFIG['OS_TEST'] != 'x86_64': + DEFINES['MOZ_NEED_LEADING_UNDERSCORE'] = True -if CONFIG['OS_ARCH'] in ('NetBSD', 'OpenBSD', 'GNU'): +if CONFIG['OS_ARCH'] in ('OpenBSD', 'GNU'): if CONFIG['CPU_ARCH'] == 'x86': - CPP_SOURCES += [ + SOURCES += [ 'xptcinvoke_gcc_x86_unix.cpp', 'xptcstubs_gcc_x86_unix.cpp' ] @@ -18,4 +18,4 @@ $NetBSD: patch-mozilla_xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.1 2013/09 +if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD', 'NetBSD', 'DragonFly') or \ CONFIG['OS_ARCH'].startswith('GNU_'): if CONFIG['OS_TEST'] == 'x86_64': - CPP_SOURCES += [ + SOURCES += [ diff --git a/www/seamonkey/patches/patch-xn b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S index 112f3c05c05..6aa14de6a6f 100644 --- a/www/seamonkey/patches/patch-xn +++ b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S @@ -1,7 +1,7 @@ -$NetBSD: patch-xn,v 1.7 2013/01/07 21:55:30 ryoon Exp $ +$NetBSD: patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S,v 1.1 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s.orig 2012-08-27 04:49:34.000000000 +0000 -+++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s +--- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S.orig 2014-03-19 01:42:18.000000000 +0000 ++++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S @@ -16,6 +16,47 @@ #include <sys/asm.h> #endif diff --git a/www/seamonkey/patches/patch-xo b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S index 0151ad6ac7f..0a09756377f 100644 --- a/www/seamonkey/patches/patch-xo +++ b/www/seamonkey/patches/patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S @@ -1,7 +1,7 @@ -$NetBSD: patch-xo,v 1.7 2013/01/07 21:55:30 ryoon Exp $ +$NetBSD: patch-mozilla_xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S,v 1.1 2014/03/30 04:13:17 ryoon Exp $ ---- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.orig 2012-08-27 04:49:34.000000000 +0000 -+++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s +--- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S.orig 2014-03-19 01:42:18.000000000 +0000 ++++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S @@ -14,6 +14,47 @@ #include <sys/asm.h> #endif diff --git a/www/seamonkey/patches/patch-mozilla_xpcom_string_public_nsAlgorithm.h b/www/seamonkey/patches/patch-mozilla_xpcom_string_public_nsAlgorithm.h deleted file mode 100644 index 7a5895567df..00000000000 --- a/www/seamonkey/patches/patch-mozilla_xpcom_string_public_nsAlgorithm.h +++ /dev/null @@ -1,16 +0,0 @@ -$NetBSD: patch-mozilla_xpcom_string_public_nsAlgorithm.h,v 1.1 2013/05/23 13:25:30 ryoon Exp $ - ---- mozilla/xpcom/string/public/nsAlgorithm.h.orig 2013-05-03 03:08:15.000000000 +0000 -+++ mozilla/xpcom/string/public/nsAlgorithm.h -@@ -45,7 +45,10 @@ XPCOM_MAX( const T& a, const T& b ) - return a > b ? a : b; - } - --#if defined(_MSC_VER) && (_MSC_VER < 1600) -+#if (defined(_MSC_VER) && (_MSC_VER < 1600)) || \ -+ ((defined(__GLIBCXX__) && __GLIBCXX__ < 20121005) && \ -+ (defined(_GLIBCXX_USE_LONG_LONG) && \ -+ (!_GLIBCXX_USE_C99 || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC))) - namespace std { - inline - long long diff --git a/www/seamonkey/patches/patch-xj b/www/seamonkey/patches/patch-xj deleted file mode 100644 index ec86ee4fd62..00000000000 --- a/www/seamonkey/patches/patch-xj +++ /dev/null @@ -1,128 +0,0 @@ -$NetBSD: patch-xj,v 1.7 2013/01/07 21:55:30 ryoon Exp $ - -NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. - ---- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp.orig 2012-11-18 10:19:54.000000000 +0000 -+++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp -@@ -6,6 +6,7 @@ - // Implement shared vtbl methods. - - #include "xptcprivate.h" -+#include "xptiprivate.h" - - // The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral - // parameters and the first 8 floating point parameters in registers -@@ -36,7 +37,6 @@ PrepareAndDispatch(nsXPTCStubBase* self, - { - nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; - nsXPTCMiniVariant* dispatchParams = NULL; -- nsIInterfaceInfo* iface_info = NULL; - const nsXPTMethodInfo* info; - uint32_t paramCount; - uint32_t i; -@@ -44,11 +44,7 @@ PrepareAndDispatch(nsXPTCStubBase* self, - - NS_ASSERTION(self,"no self"); - -- self->GetInterfaceInfo(&iface_info); -- NS_ASSERTION(iface_info,"no interface info"); -- if (! iface_info) -- return NS_ERROR_UNEXPECTED; -- -+ self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info); - iface_info->GetMethodInfo(uint16_t(methodIndex), &info); - NS_ASSERTION(info,"no method info"); - if (! info) -@@ -84,8 +80,10 @@ PrepareAndDispatch(nsXPTCStubBase* self, - if ((uint32_t) ap & 4) ap++; // doubles are 8-byte aligned on stack - dp->val.d = *(double*) ap; - ap += 2; -+#if __GXX_ABI_VERSION < 100 - if (gpr < GPR_COUNT) - gpr += 2; -+#endif - } - continue; - } -@@ -95,8 +93,10 @@ PrepareAndDispatch(nsXPTCStubBase* self, - else { - dp->val.f = *(float*) ap; - ap += 1; -+#if __GXX_ABI_VERSION < 100 - if (gpr < GPR_COUNT) - gpr += 1; -+#endif - } - continue; - } -@@ -144,9 +144,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, - } - } - -- result = self->CallMethod((uint16_t) methodIndex, info, dispatchParams); -- -- NS_RELEASE(iface_info); -+ result = self->mOuter->CallMethod((PRUint16) methodIndex, -+ info, -+ dispatchParams); - - if (dispatchParams != paramBuffer) - delete [] dispatchParams; -@@ -160,7 +160,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, - // however, it's quick, dirty, and'll break when the ABI changes on - // us, which is what we want ;-). - --#define STUB_ENTRY(n) \ -+#if __GXX_ABI_VERSION < 100 -+// gcc-2 version -+# define STUB_ENTRY(n) \ - __asm__ ( \ - ".section \".text\" \n\t" \ - ".align 2 \n\t" \ -@@ -171,6 +173,46 @@ __asm__ ( - "li 11,"#n" \n\t" \ - "b SharedStub@local \n" \ - ); -+#else -+// gcc-3 version -+// -+// As G++3 ABI contains the length of the functionname in the mangled -+// name, it is difficult to get a generic assembler mechanism like -+// in the G++ 2.95 case. -+// Create names would be like: -+// _ZN14nsXPTCStubBase5Stub1Ev -+// _ZN14nsXPTCStubBase6Stub12Ev -+// _ZN14nsXPTCStubBase7Stub123Ev -+// _ZN14nsXPTCStubBase8Stub1234Ev -+// etc. -+// Use assembler directives to get the names right... -+ -+# define STUB_ENTRY(n) \ -+__asm__ ( \ -+ ".align 2 \n\t" \ -+ ".if "#n" < 10 \n\t" \ -+ ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ -+ ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \ -+"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \ -+ \ -+ ".elseif "#n" < 100 \n\t" \ -+ ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ -+ ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \ -+"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \ -+ \ -+ ".elseif "#n" < 1000 \n\t" \ -+ ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ -+ ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \ -+"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \ -+ \ -+ ".else \n\t" \ -+ ".err \"stub number "#n" >= 1000 not yet supported\"\n" \ -+ ".endif \n\t" \ -+ \ -+ "li 11,"#n" \n\t" \ -+ "b SharedStub@local \n" \ -+); -+#endif - - #define SENTINEL_ENTRY(n) \ - nsresult nsXPTCStubBase::Sentinel##n() \ diff --git a/www/seamonkey/patches/patch-xk b/www/seamonkey/patches/patch-xk deleted file mode 100644 index 19a5bdfa4e7..00000000000 --- a/www/seamonkey/patches/patch-xk +++ /dev/null @@ -1,72 +0,0 @@ -$NetBSD: patch-xk,v 1.7 2013/01/07 21:55:30 ryoon Exp $ - -NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. - ---- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s.orig 2012-11-18 10:19:54.000000000 +0000 -+++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s -@@ -25,23 +25,23 @@ - .type SharedStub,@function - - SharedStub: -- stwu sp,-112(sp) # room for -- # linkage (8), -- # gprData (32), -- # fprData (64), -- # stack alignment(8) -+ stwu sp,-112(sp) // room for -+ // linkage (8), -+ // gprData (32), -+ // fprData (64), -+ // stack alignment(8) - mflr r0 -- stw r0,116(sp) # save LR backchain -+ stw r0,116(sp) // save LR backchain - -- stw r4,12(sp) # save GP registers -- stw r5,16(sp) # (n.b. that we don't save r3 -- stw r6,20(sp) # because PrepareAndDispatch() is savvy) -+ stw r4,12(sp) // save GP registers -+ stw r5,16(sp) // (n.b. that we don't save r3 -+ stw r6,20(sp) // because PrepareAndDispatch() is savvy) - stw r7,24(sp) - stw r8,28(sp) - stw r9,32(sp) - stw r10,36(sp) - -- stfd f1,40(sp) # save FP registers -+ stfd f1,40(sp) // save FP registers - stfd f2,48(sp) - stfd f3,56(sp) - stfd f4,64(sp) -@@ -50,21 +50,21 @@ SharedStub: - stfd f7,88(sp) - stfd f8,96(sp) - -- # r3 has the 'self' pointer already -+ // r3 has the 'self' pointer already - -- mr r4,r11 # r4 <= methodIndex selector, passed -- # via r11 in the nsXPTCStubBase::StubXX() call -+ mr r4,r11 // r4 <= methodIndex selector, passed -+ // via r11 in the nsXPTCStubBase::StubXX() call - -- addi r5,sp,120 # r5 <= pointer to callers args area, -- # beyond r3-r10/f1-f8 mapped range -+ addi r5,sp,120 // r5 <= pointer to callers args area, -+ // beyond r3-r10/f1-f8 mapped range - -- addi r6,sp,8 # r6 <= gprData -- addi r7,sp,40 # r7 <= fprData -+ addi r6,sp,8 // r6 <= gprData -+ addi r7,sp,40 // r7 <= fprData - -- bl PrepareAndDispatch@local # Go! -+ bl PrepareAndDispatch@local // Go! - -- lwz r0,116(sp) # restore LR -+ lwz r0,116(sp) // restore LR - mtlr r0 -- la sp,112(sp) # clean up the stack -+ la sp,112(sp) // clean up the stack - blr - diff --git a/www/seamonkey/patches/patch-xl b/www/seamonkey/patches/patch-xl index 4a1193ac931..b67b7ace2b6 100644 --- a/www/seamonkey/patches/patch-xl +++ b/www/seamonkey/patches/patch-xl @@ -1,10 +1,10 @@ -$NetBSD: patch-xl,v 1.7 2013/01/07 21:55:30 ryoon Exp $ +$NetBSD: patch-xl,v 1.8 2014/03/30 04:13:17 ryoon Exp $ NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. ---- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s.orig 2012-11-18 10:19:54.000000000 +0000 +--- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s.orig 2014-03-19 01:42:18.000000000 +0000 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s -@@ -20,41 +20,42 @@ +@@ -20,15 +20,15 @@ .section ".text" .align 2 @@ -12,63 +12,16 @@ NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. - .type XPTC_InvokeByIndex,@function + .globl NS_InvokeByIndex_P + .type NS_InvokeByIndex_P,@function -+ -+// -+// NS_InvokeByIndex_P(nsISupports* that, PRUint32 methodIndex, -+// PRUint32 paramCount, nsXPTCVariant* params) -+// -+ -+NS_InvokeByIndex_P: -+ stwu sp,-32(sp) // setup standard stack frame -+ mflr r0 // save LR -+ stw r3,8(sp) // r3 <= that -+ stw r4,12(sp) // r4 <= methodIndex --# + # -# XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex, -# uint32_t paramCount, nsXPTCVariant* params) --# -- --XPTC_InvokeByIndex: -- stwu sp,-32(sp) # setup standard stack frame -- mflr r0 # save LR -- stw r3,8(sp) # r3 <= that -- stw r4,12(sp) # r4 <= methodIndex - stw r30,16(sp) - stw r31,20(sp) - -- stw r0,36(sp) # store LR backchain -+ stw r0,36(sp) // store LR backchain - mr r31,sp - -- rlwinm r10,r5,3,0,27 # r10 = (ParamCount * 2 * 4) & ~0x0f -- addi r0,r10,96 # reserve stack for GPR and FPR register save area r0 = r10 + 96 -- lwz r9,0(sp) # r9 = backchain -+ rlwinm r10,r5,3,0,27 // r10 = (ParamCount * 2 * 4) & ~0x0f -+ addi r0,r10,96 // reserve stack for GPR and FPR register save area r0 = r10 + 96 -+ lwz r9,0(sp) // r9 = backchain - neg r0,r0 -- stwux r9,sp,r0 # reserve stack sapce and save SP backchain -+ stwux r9,sp,r0 // reserve stack sapce and save SP backchain - -- addi r3,sp,8 # r3 <= args -- mr r4,r5 # r4 <= paramCount -- mr r5,r6 # r5 <= params -- add r6,r3,r10 # r6 <= gpregs ( == args + r10 ) -- mr r30,r6 # store in r30 for use later... -- addi r7,r6,32 # r7 <= fpregs ( == gpregs + 32 ) -+ addi r3,sp,8 // r3 <= args -+ mr r4,r5 // r4 <= paramCount -+ mr r5,r6 // r5 <= params -+ add r6,r3,r10 // r6 <= gpregs ( == args + r10 ) -+ mr r30,r6 // store in r30 for use later... -+ addi r7,r6,32 // r7 <= fpregs ( == gpregs + 32 ) ++# NS_InvokeByIndex_P(nsISupports* that, PRUint32 methodIndex, ++# PRUint32 paramCount, nsXPTCVariant* params) + # -- bl invoke_copy_to_stack@local # (args, paramCount, params, gpregs, fpregs) -+ bl invoke_copy_to_stack@local // (args, paramCount, params, gpregs, fpregs) - -- lfd f1,32(r30) # load FP registers with method parameters -+ lfd f1,32(r30) // load FP registers with method parameters - lfd f2,40(r30) - lfd f3,48(r30) - lfd f4,56(r30) +-XPTC_InvokeByIndex: ++NS_InvokeByIndex_P: + stwu sp,-32(sp) # setup standard stack frame + mflr r0 # save LR + stw r3,8(sp) # r3 <= that |