summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-08-27 23:52:56 -0500
committersanine <sanine.not@pm.me>2022-08-27 23:52:56 -0500
commita4dd0ad63c00f4dee3b86dfd3075d1d61b2b3180 (patch)
tree13bd5bfa15e6fea2a12f176bae79adf9c6fd0933
parentbde3e4f1bb7b8f8abca0884a7d994ee1c17a66b1 (diff)
add plibsys
-rw-r--r--3rdparty/plibsys/.codedocs53
-rw-r--r--3rdparty/plibsys/.gear/plibsys.spec104
-rw-r--r--3rdparty/plibsys/.gear/rules2
-rw-r--r--3rdparty/plibsys/.travis.yml171
-rw-r--r--3rdparty/plibsys/3dparty/scosv/FSU-threads-3.14.tgzbin0 -> 320682 bytes
-rw-r--r--3rdparty/plibsys/AUTHORS2
-rw-r--r--3rdparty/plibsys/CMakeLists.txt93
-rw-r--r--3rdparty/plibsys/COPYING20
-rw-r--r--3rdparty/plibsys/Doxyfile.in180
-rw-r--r--3rdparty/plibsys/NEWS122
-rw-r--r--3rdparty/plibsys/README.md115
-rw-r--r--3rdparty/plibsys/appveyor.yml289
-rw-r--r--3rdparty/plibsys/cmake/PlatformDetect.cmake144
-rw-r--r--3rdparty/plibsys/cmake/StdargDetect.cmake74
-rw-r--r--3rdparty/plibsys/cmake/ThreadNameDetect.cmake135
-rw-r--r--3rdparty/plibsys/cmake/VisibilityDetect.cmake127
-rw-r--r--3rdparty/plibsys/codecov.yml7
-rw-r--r--3rdparty/plibsys/platforms/aix-gcc/platform.cmake13
-rw-r--r--3rdparty/plibsys/platforms/amigaos-gcc/Platform/AmigaOS.cmake2
-rw-r--r--3rdparty/plibsys/platforms/amigaos-gcc/amigaos.cmake90
-rw-r--r--3rdparty/plibsys/platforms/amigaos-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/android-clang/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/android-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/bb10-qcc/blackberry.cmake141
-rw-r--r--3rdparty/plibsys/platforms/beos-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/common/HPUX.cmake15
-rw-r--r--3rdparty/plibsys/platforms/common/SCOSV.cmake9
-rw-r--r--3rdparty/plibsys/platforms/cygwin-clang/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/cygwin-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/darwin-clang/platform.cmake9
-rw-r--r--3rdparty/plibsys/platforms/darwin-gcc/platform.cmake9
-rw-r--r--3rdparty/plibsys/platforms/darwin-icc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/darwin-pgi/platform.cmake27
-rw-r--r--3rdparty/plibsys/platforms/dragonfly-clang/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/dragonfly-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/freebsd-clang/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/freebsd-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/haiku-clang/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/haiku-gcc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/hpux-gcc/platform.cmake16
-rw-r--r--3rdparty/plibsys/platforms/ios-clang/ios.cmake419
-rw-r--r--3rdparty/plibsys/platforms/ios-clang/platform.cmake9
-rw-r--r--3rdparty/plibsys/platforms/irix64-gcc/platform.cmake13
-rw-r--r--3rdparty/plibsys/platforms/irix64-mipspro/platform.cmake13
-rw-r--r--3rdparty/plibsys/platforms/linux-clang/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/linux-cray/platform.cmake18
-rw-r--r--3rdparty/plibsys/platforms/linux-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/linux-icc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/linux-pgi/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/linux-xlc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/msys-clang/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/msys-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/netbsd-clang/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/netbsd-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/openbsd-clang/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/openbsd-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/os2-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/qnx-qcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/scosv-gcc/platform.cmake27
-rw-r--r--3rdparty/plibsys/platforms/sunos-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/sunos-sunpro/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/syllable-gcc/platform.cmake12
-rw-r--r--3rdparty/plibsys/platforms/tru64-compaq/platform.cmake17
-rw-r--r--3rdparty/plibsys/platforms/tru64-gcc/platform.cmake16
-rw-r--r--3rdparty/plibsys/platforms/unixware-gcc/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/vms-general/README.md49
-rw-r--r--3rdparty/plibsys/platforms/vms-general/build_vms.com616
-rw-r--r--3rdparty/plibsys/platforms/vms-general/plibsys.opt540
-rw-r--r--3rdparty/plibsys/platforms/vms-general/vms_shorten_symbol.c238
-rw-r--r--3rdparty/plibsys/platforms/win32-borland/platform.cmake8
-rw-r--r--3rdparty/plibsys/platforms/win32-clang/platform.cmake8
-rw-r--r--3rdparty/plibsys/platforms/win32-gcc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/win32-icc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/win32-msvc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/win32-watcom/platform.cmake11
-rw-r--r--3rdparty/plibsys/platforms/win64-clang/platform.cmake8
-rw-r--r--3rdparty/plibsys/platforms/win64-gcc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/win64-icc/platform.cmake7
-rw-r--r--3rdparty/plibsys/platforms/win64-msvc/platform.cmake7
-rwxr-xr-x3rdparty/plibsys/scripts/run_tests.sh70
-rw-r--r--3rdparty/plibsys/src/CMakeLists.txt996
-rw-r--r--3rdparty/plibsys/src/patomic-c11.c182
-rw-r--r--3rdparty/plibsys/src/patomic-decc.c286
-rw-r--r--3rdparty/plibsys/src/patomic-sim.c268
-rw-r--r--3rdparty/plibsys/src/patomic-sync.c190
-rw-r--r--3rdparty/plibsys/src/patomic-win.c272
-rw-r--r--3rdparty/plibsys/src/patomic.h310
-rw-r--r--3rdparty/plibsys/src/pcondvariable-amiga.c230
-rw-r--r--3rdparty/plibsys/src/pcondvariable-atheos.c234
-rw-r--r--3rdparty/plibsys/src/pcondvariable-beos.c233
-rw-r--r--3rdparty/plibsys/src/pcondvariable-none.c80
-rw-r--r--3rdparty/plibsys/src/pcondvariable-os2.c163
-rw-r--r--3rdparty/plibsys/src/pcondvariable-posix.c121
-rw-r--r--3rdparty/plibsys/src/pcondvariable-solaris.c122
-rw-r--r--3rdparty/plibsys/src/pcondvariable-win.c312
-rw-r--r--3rdparty/plibsys/src/pcondvariable.h138
-rw-r--r--3rdparty/plibsys/src/pcryptohash-gost3411.c484
-rw-r--r--3rdparty/plibsys/src/pcryptohash-gost3411.h53
-rw-r--r--3rdparty/plibsys/src/pcryptohash-md5.c273
-rw-r--r--3rdparty/plibsys/src/pcryptohash-md5.h51
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha1.c321
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha1.h51
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha2-256.c286
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha2-256.h59
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha2-512.c300
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha2-512.h59
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha3.c297
-rw-r--r--3rdparty/plibsys/src/pcryptohash-sha3.h79
-rw-r--r--3rdparty/plibsys/src/pcryptohash.c250
-rw-r--r--3rdparty/plibsys/src/pcryptohash.h188
-rw-r--r--3rdparty/plibsys/src/pdir-none.c124
-rw-r--r--3rdparty/plibsys/src/pdir-os2.c381
-rw-r--r--3rdparty/plibsys/src/pdir-posix.c378
-rw-r--r--3rdparty/plibsys/src/pdir-win.c291
-rw-r--r--3rdparty/plibsys/src/pdir.c37
-rw-r--r--3rdparty/plibsys/src/pdir.h177
-rw-r--r--3rdparty/plibsys/src/perror-private.h67
-rw-r--r--3rdparty/plibsys/src/perror.c878
-rw-r--r--3rdparty/plibsys/src/perror.h249
-rw-r--r--3rdparty/plibsys/src/perrortypes.h106
-rw-r--r--3rdparty/plibsys/src/pfile.c80
-rw-r--r--3rdparty/plibsys/src/pfile.h87
-rw-r--r--3rdparty/plibsys/src/phashtable.c243
-rw-r--r--3rdparty/plibsys/src/phashtable.h167
-rw-r--r--3rdparty/plibsys/src/pinifile.c503
-rw-r--r--3rdparty/plibsys/src/pinifile.h261
-rw-r--r--3rdparty/plibsys/src/pipc-private.h76
-rw-r--r--3rdparty/plibsys/src/pipc.c178
-rw-r--r--3rdparty/plibsys/src/plibraryloader-amiga.c583
-rw-r--r--3rdparty/plibsys/src/plibraryloader-beos.c142
-rw-r--r--3rdparty/plibsys/src/plibraryloader-none.c75
-rw-r--r--3rdparty/plibsys/src/plibraryloader-os2.c155
-rw-r--r--3rdparty/plibsys/src/plibraryloader-posix.c148
-rw-r--r--3rdparty/plibsys/src/plibraryloader-shl.c140
-rw-r--r--3rdparty/plibsys/src/plibraryloader-win.c140
-rw-r--r--3rdparty/plibsys/src/plibraryloader.h155
-rw-r--r--3rdparty/plibsys/src/plibsys-private.h86
-rw-r--r--3rdparty/plibsys/src/plibsys.h64
-rw-r--r--3rdparty/plibsys/src/plibsysconfig.h.in76
-rw-r--r--3rdparty/plibsys/src/plist.c174
-rw-r--r--3rdparty/plibsys/src/plist.h199
-rw-r--r--3rdparty/plibsys/src/pmacros.h302
-rw-r--r--3rdparty/plibsys/src/pmacroscompiler.h253
-rw-r--r--3rdparty/plibsys/src/pmacroscpu.h627
-rw-r--r--3rdparty/plibsys/src/pmacrosos.h500
-rw-r--r--3rdparty/plibsys/src/pmain.c132
-rw-r--r--3rdparty/plibsys/src/pmain.h209
-rw-r--r--3rdparty/plibsys/src/pmem.c357
-rw-r--r--3rdparty/plibsys/src/pmem.h191
-rw-r--r--3rdparty/plibsys/src/pmutex-amiga.c101
-rw-r--r--3rdparty/plibsys/src/pmutex-atheos.c111
-rw-r--r--3rdparty/plibsys/src/pmutex-beos.c110
-rw-r--r--3rdparty/plibsys/src/pmutex-none.c66
-rw-r--r--3rdparty/plibsys/src/pmutex-os2.c112
-rw-r--r--3rdparty/plibsys/src/pmutex-posix.c104
-rw-r--r--3rdparty/plibsys/src/pmutex-solaris.c105
-rw-r--r--3rdparty/plibsys/src/pmutex-win.c92
-rw-r--r--3rdparty/plibsys/src/pmutex.h136
-rw-r--r--3rdparty/plibsys/src/pprocess.c61
-rw-r--r--3rdparty/plibsys/src/pprocess.h69
-rw-r--r--3rdparty/plibsys/src/prwlock-general.c326
-rw-r--r--3rdparty/plibsys/src/prwlock-none.c103
-rw-r--r--3rdparty/plibsys/src/prwlock-posix.c151
-rw-r--r--3rdparty/plibsys/src/prwlock-solaris.c151
-rw-r--r--3rdparty/plibsys/src/prwlock-win.c548
-rw-r--r--3rdparty/plibsys/src/prwlock.h185
-rw-r--r--3rdparty/plibsys/src/psemaphore-amiga.c250
-rw-r--r--3rdparty/plibsys/src/psemaphore-none.c91
-rw-r--r--3rdparty/plibsys/src/psemaphore-os2.c91
-rw-r--r--3rdparty/plibsys/src/psemaphore-posix.c272
-rw-r--r--3rdparty/plibsys/src/psemaphore-sysv.c319
-rw-r--r--3rdparty/plibsys/src/psemaphore-win.c204
-rw-r--r--3rdparty/plibsys/src/psemaphore.h191
-rw-r--r--3rdparty/plibsys/src/pshm-amiga.c274
-rw-r--r--3rdparty/plibsys/src/pshm-none.c94
-rw-r--r--3rdparty/plibsys/src/pshm-os2.c350
-rw-r--r--3rdparty/plibsys/src/pshm-posix.c311
-rw-r--r--3rdparty/plibsys/src/pshm-sysv.c307
-rw-r--r--3rdparty/plibsys/src/pshm-win.c262
-rw-r--r--3rdparty/plibsys/src/pshm.h195
-rw-r--r--3rdparty/plibsys/src/pshmbuffer.c334
-rw-r--r--3rdparty/plibsys/src/pshmbuffer.h191
-rw-r--r--3rdparty/plibsys/src/psocket.c1644
-rw-r--r--3rdparty/plibsys/src/psocket.h779
-rw-r--r--3rdparty/plibsys/src/psocketaddress.c619
-rw-r--r--3rdparty/plibsys/src/psocketaddress.h284
-rw-r--r--3rdparty/plibsys/src/pspinlock-c11.c103
-rw-r--r--3rdparty/plibsys/src/pspinlock-decc.c87
-rw-r--r--3rdparty/plibsys/src/pspinlock-sim.c88
-rw-r--r--3rdparty/plibsys/src/pspinlock-sync.c83
-rw-r--r--3rdparty/plibsys/src/pspinlock-win.c83
-rw-r--r--3rdparty/plibsys/src/pspinlock.h142
-rw-r--r--3rdparty/plibsys/src/pstdarg.h318
-rw-r--r--3rdparty/plibsys/src/pstring.c206
-rw-r--r--3rdparty/plibsys/src/pstring.h117
-rw-r--r--3rdparty/plibsys/src/psysclose-darwin.c93
-rw-r--r--3rdparty/plibsys/src/psysclose-private.h47
-rw-r--r--3rdparty/plibsys/src/psysclose-unix.c54
-rw-r--r--3rdparty/plibsys/src/psysclose-win.c33
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-amiga.c70
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-beos.c51
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-generic.c58
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-mach.c73
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-os2.c107
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-posix.c109
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-private.h45
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-solaris.c53
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler-win.c169
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler.c70
-rw-r--r--3rdparty/plibsys/src/ptimeprofiler.h93
-rw-r--r--3rdparty/plibsys/src/ptree-avl.c481
-rw-r--r--3rdparty/plibsys/src/ptree-avl.h58
-rw-r--r--3rdparty/plibsys/src/ptree-bst.c140
-rw-r--r--3rdparty/plibsys/src/ptree-bst.h58
-rw-r--r--3rdparty/plibsys/src/ptree-private.h48
-rw-r--r--3rdparty/plibsys/src/ptree-rb.c484
-rw-r--r--3rdparty/plibsys/src/ptree-rb.h58
-rw-r--r--3rdparty/plibsys/src/ptree.c315
-rw-r--r--3rdparty/plibsys/src/ptree.h230
-rw-r--r--3rdparty/plibsys/src/ptypes.h1122
-rw-r--r--3rdparty/plibsys/src/puthread-amiga.c673
-rw-r--r--3rdparty/plibsys/src/puthread-atheos.c317
-rw-r--r--3rdparty/plibsys/src/puthread-beos.c431
-rw-r--r--3rdparty/plibsys/src/puthread-none.c142
-rw-r--r--3rdparty/plibsys/src/puthread-os2.c458
-rw-r--r--3rdparty/plibsys/src/puthread-posix.c580
-rw-r--r--3rdparty/plibsys/src/puthread-private.h53
-rw-r--r--3rdparty/plibsys/src/puthread-solaris.c352
-rw-r--r--3rdparty/plibsys/src/puthread-win.c511
-rw-r--r--3rdparty/plibsys/src/puthread.c558
-rw-r--r--3rdparty/plibsys/src/puthread.h311
-rw-r--r--3rdparty/plibsys/tests/CMakeLists.txt96
-rw-r--r--3rdparty/plibsys/tests/patomic_test.cpp118
-rw-r--r--3rdparty/plibsys/tests/pcondvariable_test.cpp230
-rw-r--r--3rdparty/plibsys/tests/pcryptohash_test.cpp662
-rw-r--r--3rdparty/plibsys/tests/pdir_test.cpp248
-rw-r--r--3rdparty/plibsys/tests/perror_test.cpp236
-rw-r--r--3rdparty/plibsys/tests/pfile_test.cpp61
-rw-r--r--3rdparty/plibsys/tests/phashtable_test.cpp320
-rw-r--r--3rdparty/plibsys/tests/pinifile_test.cpp357
-rw-r--r--3rdparty/plibsys/tests/plibraryloader_test.cpp179
-rw-r--r--3rdparty/plibsys/tests/plist_test.cpp200
-rw-r--r--3rdparty/plibsys/tests/pmacros_test.cpp646
-rw-r--r--3rdparty/plibsys/tests/pmain_test.cpp111
-rw-r--r--3rdparty/plibsys/tests/pmem_test.cpp171
-rw-r--r--3rdparty/plibsys/tests/pmutex_test.cpp146
-rw-r--r--3rdparty/plibsys/tests/pprocess_test.cpp49
-rw-r--r--3rdparty/plibsys/tests/prwlock_test.cpp224
-rw-r--r--3rdparty/plibsys/tests/psemaphore_test.cpp226
-rw-r--r--3rdparty/plibsys/tests/pshm_test.cpp313
-rw-r--r--3rdparty/plibsys/tests/pshmbuffer_test.cpp352
-rw-r--r--3rdparty/plibsys/tests/psocket_test.cpp1131
-rw-r--r--3rdparty/plibsys/tests/psocketaddress_test.cpp338
-rw-r--r--3rdparty/plibsys/tests/pspinlock_test.cpp148
-rw-r--r--3rdparty/plibsys/tests/pstdarg_test.cpp205
-rw-r--r--3rdparty/plibsys/tests/pstring_test.cpp289
-rw-r--r--3rdparty/plibsys/tests/ptestmacros.h131
-rw-r--r--3rdparty/plibsys/tests/ptimeprofiler_test.cpp126
-rw-r--r--3rdparty/plibsys/tests/ptree_test.cpp633
-rw-r--r--3rdparty/plibsys/tests/ptypes_test.cpp456
-rw-r--r--3rdparty/plibsys/tests/puthread_test.cpp481
-rw-r--r--3rdparty/portaudio/.editorconfig (renamed from portaudio/.editorconfig)0
-rw-r--r--3rdparty/portaudio/.gitattributes (renamed from portaudio/.gitattributes)0
-rw-r--r--3rdparty/portaudio/.github/ISSUE_TEMPLATE/bug_report.md (renamed from portaudio/.github/ISSUE_TEMPLATE/bug_report.md)0
-rw-r--r--3rdparty/portaudio/.github/workflows/MSBuild.yml (renamed from portaudio/.github/workflows/MSBuild.yml)0
-rw-r--r--3rdparty/portaudio/.github/workflows/c-cpp.yml (renamed from portaudio/.github/workflows/c-cpp.yml)0
-rw-r--r--3rdparty/portaudio/.gitignore (renamed from portaudio/.gitignore)0
-rw-r--r--3rdparty/portaudio/CMakeLists.txt (renamed from portaudio/CMakeLists.txt)0
-rw-r--r--3rdparty/portaudio/Doxyfile (renamed from portaudio/Doxyfile)0
-rw-r--r--3rdparty/portaudio/Doxyfile.developer (renamed from portaudio/Doxyfile.developer)0
-rw-r--r--3rdparty/portaudio/LICENSE.txt (renamed from portaudio/LICENSE.txt)0
-rw-r--r--3rdparty/portaudio/Makefile.in (renamed from portaudio/Makefile.in)0
-rw-r--r--3rdparty/portaudio/README.configure.txt (renamed from portaudio/README.configure.txt)0
-rw-r--r--3rdparty/portaudio/README.md (renamed from portaudio/README.md)0
-rw-r--r--3rdparty/portaudio/SConstruct (renamed from portaudio/SConstruct)0
-rw-r--r--3rdparty/portaudio/aclocal.m4 (renamed from portaudio/aclocal.m4)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/AUTHORS (renamed from portaudio/bindings/cpp/AUTHORS)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/COPYING (renamed from portaudio/bindings/cpp/COPYING)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/ChangeLog (renamed from portaudio/bindings/cpp/ChangeLog)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/INSTALL (renamed from portaudio/bindings/cpp/INSTALL)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/Makefile.am (renamed from portaudio/bindings/cpp/Makefile.am)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/Makefile.in (renamed from portaudio/bindings/cpp/Makefile.in)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/NEWS (renamed from portaudio/bindings/cpp/NEWS)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/README (renamed from portaudio/bindings/cpp/README)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/SConscript (renamed from portaudio/bindings/cpp/SConscript)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/aclocal.m4 (renamed from portaudio/bindings/cpp/aclocal.m4)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/bin/Makefile.am (renamed from portaudio/bindings/cpp/bin/Makefile.am)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/bin/Makefile.in (renamed from portaudio/bindings/cpp/bin/Makefile.in)0
-rwxr-xr-x3rdparty/portaudio/bindings/cpp/configure (renamed from portaudio/bindings/cpp/configure)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/configure.ac (renamed from portaudio/bindings/cpp/configure.ac)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/doc/Makefile.am (renamed from portaudio/bindings/cpp/doc/Makefile.am)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/doc/Makefile.in (renamed from portaudio/bindings/cpp/doc/Makefile.in)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/doc/README (renamed from portaudio/bindings/cpp/doc/README)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/doc/config.doxy (renamed from portaudio/bindings/cpp/doc/config.doxy)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/doc/config.doxy.linux (renamed from portaudio/bindings/cpp/doc/config.doxy.linux)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/example/devs.cxx (renamed from portaudio/bindings/cpp/example/devs.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/example/sine.cxx (renamed from portaudio/bindings/cpp/example/sine.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/Makefile.am (renamed from portaudio/bindings/cpp/include/Makefile.am)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/Makefile.in (renamed from portaudio/bindings/cpp/include/Makefile.in)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/Device.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/System.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/System.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx (renamed from portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/lib/Makefile.am (renamed from portaudio/bindings/cpp/lib/Makefile.am)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/lib/Makefile.in (renamed from portaudio/bindings/cpp/lib/Makefile.in)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/portaudiocpp.pc.in (renamed from portaudio/bindings/cpp/portaudiocpp.pc.in)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/Device.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/System.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/System.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx (renamed from portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c (renamed from portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h (renamed from portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.c (renamed from portaudio/bindings/java/c/src/com_portaudio_PortAudio.c)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.h (renamed from portaudio/bindings/java/c/src/com_portaudio_PortAudio.h)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/jpa_tools.c (renamed from portaudio/bindings/java/c/src/jpa_tools.c)0
-rw-r--r--3rdparty/portaudio/bindings/java/c/src/jpa_tools.h (renamed from portaudio/bindings/java/c/src/jpa_tools.h)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio.dox (renamed from portaudio/bindings/java/jportaudio.dox)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/.classpath (renamed from portaudio/bindings/java/jportaudio/.classpath)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/.project (renamed from portaudio/bindings/java/jportaudio/.project)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java (renamed from portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java (renamed from portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java (renamed from portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java)0
-rw-r--r--3rdparty/portaudio/bindings/java/scripts/make_header.bat (renamed from portaudio/bindings/java/scripts/make_header.bat)0
-rwxr-xr-x3rdparty/portaudio/clear_gitrevision.sh (renamed from portaudio/clear_gitrevision.sh)0
-rw-r--r--3rdparty/portaudio/cmake_support/FindASIOSDK.cmake (renamed from portaudio/cmake_support/FindASIOSDK.cmake)0
-rw-r--r--3rdparty/portaudio/cmake_support/FindJack.cmake (renamed from portaudio/cmake_support/FindJack.cmake)0
-rw-r--r--3rdparty/portaudio/cmake_support/cmake_uninstall.cmake.in (renamed from portaudio/cmake_support/cmake_uninstall.cmake.in)0
-rw-r--r--3rdparty/portaudio/cmake_support/options_cmake.h.in (renamed from portaudio/cmake_support/options_cmake.h.in)0
-rw-r--r--3rdparty/portaudio/cmake_support/portaudio-2.0.pc.in (renamed from portaudio/cmake_support/portaudio-2.0.pc.in)0
-rw-r--r--3rdparty/portaudio/cmake_support/portaudioConfig.cmake.in (renamed from portaudio/cmake_support/portaudioConfig.cmake.in)0
-rw-r--r--3rdparty/portaudio/cmake_support/template_portaudio.def (renamed from portaudio/cmake_support/template_portaudio.def)0
-rwxr-xr-x3rdparty/portaudio/config.guess (renamed from portaudio/config.guess)0
-rwxr-xr-x3rdparty/portaudio/config.sub (renamed from portaudio/config.sub)0
-rwxr-xr-x3rdparty/portaudio/configure (renamed from portaudio/configure)0
-rw-r--r--3rdparty/portaudio/configure.in (renamed from portaudio/configure.in)0
-rwxr-xr-x3rdparty/portaudio/depcomp (renamed from portaudio/depcomp)0
-rw-r--r--3rdparty/portaudio/doc/src/api_overview.dox (renamed from portaudio/doc/src/api_overview.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/images/portaudio-external-architecture-diagram.png (renamed from portaudio/doc/src/images/portaudio-external-architecture-diagram.png)bin20386 -> 20386 bytes
-rw-r--r--3rdparty/portaudio/doc/src/license.dox (renamed from portaudio/doc/src/license.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/mainpage.dox (renamed from portaudio/doc/src/mainpage.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/srcguide.dox (renamed from portaudio/doc/src/srcguide.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/blocking_read_write.dox (renamed from portaudio/doc/src/tutorial/blocking_read_write.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_cmake.dox (renamed from portaudio/doc/src/tutorial/compile_cmake.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_linux.dox (renamed from portaudio/doc/src/tutorial/compile_linux.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox (renamed from portaudio/doc/src/tutorial/compile_mac_coreaudio.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_windows.dox (renamed from portaudio/doc/src/tutorial/compile_windows.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox (renamed from portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/compile_windows_mingw.dox (renamed from portaudio/doc/src/tutorial/compile_windows_mingw.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/exploring.dox (renamed from portaudio/doc/src/tutorial/exploring.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/initializing_portaudio.dox (renamed from portaudio/doc/src/tutorial/initializing_portaudio.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/open_default_stream.dox (renamed from portaudio/doc/src/tutorial/open_default_stream.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/querying_devices.dox (renamed from portaudio/doc/src/tutorial/querying_devices.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/start_stop_abort.dox (renamed from portaudio/doc/src/tutorial/start_stop_abort.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/terminating_portaudio.dox (renamed from portaudio/doc/src/tutorial/terminating_portaudio.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox (renamed from portaudio/doc/src/tutorial/tutorial_start.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/utility_functions.dox (renamed from portaudio/doc/src/tutorial/utility_functions.dox)0
-rw-r--r--3rdparty/portaudio/doc/src/tutorial/writing_a_callback.dox (renamed from portaudio/doc/src/tutorial/writing_a_callback.dox)0
-rw-r--r--3rdparty/portaudio/doc/utils/checkfiledocs.py (renamed from portaudio/doc/utils/checkfiledocs.py)0
-rw-r--r--3rdparty/portaudio/examples/CMakeLists.txt (renamed from portaudio/examples/CMakeLists.txt)0
-rw-r--r--3rdparty/portaudio/examples/pa_devs.c (renamed from portaudio/examples/pa_devs.c)0
-rw-r--r--3rdparty/portaudio/examples/pa_fuzz.c (renamed from portaudio/examples/pa_fuzz.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_mono_asio_channel_select.c (renamed from portaudio/examples/paex_mono_asio_channel_select.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_ocean_shore.c (renamed from portaudio/examples/paex_ocean_shore.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_pink.c (renamed from portaudio/examples/paex_pink.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_read_write_wire.c (renamed from portaudio/examples/paex_read_write_wire.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_record.c (renamed from portaudio/examples/paex_record.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_record_file.c (renamed from portaudio/examples/paex_record_file.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_saw.c (renamed from portaudio/examples/paex_saw.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_sine.c (renamed from portaudio/examples/paex_sine.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_sine_c++.cpp (renamed from portaudio/examples/paex_sine_c++.cpp)0
-rw-r--r--3rdparty/portaudio/examples/paex_wmme_ac3.c (renamed from portaudio/examples/paex_wmme_ac3.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_wmme_surround.c (renamed from portaudio/examples/paex_wmme_surround.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_write_sine.c (renamed from portaudio/examples/paex_write_sine.c)0
-rw-r--r--3rdparty/portaudio/examples/paex_write_sine_nonint.c (renamed from portaudio/examples/paex_write_sine_nonint.c)0
-rw-r--r--3rdparty/portaudio/i686-w64-mingw32.cmake (renamed from portaudio/i686-w64-mingw32.cmake)0
-rw-r--r--3rdparty/portaudio/include/pa_asio.h (renamed from portaudio/include/pa_asio.h)0
-rw-r--r--3rdparty/portaudio/include/pa_jack.h (renamed from portaudio/include/pa_jack.h)0
-rw-r--r--3rdparty/portaudio/include/pa_linux_alsa.h (renamed from portaudio/include/pa_linux_alsa.h)0
-rw-r--r--3rdparty/portaudio/include/pa_mac_core.h (renamed from portaudio/include/pa_mac_core.h)0
-rw-r--r--3rdparty/portaudio/include/pa_win_ds.h (renamed from portaudio/include/pa_win_ds.h)0
-rw-r--r--3rdparty/portaudio/include/pa_win_wasapi.h (renamed from portaudio/include/pa_win_wasapi.h)0
-rw-r--r--3rdparty/portaudio/include/pa_win_waveformat.h (renamed from portaudio/include/pa_win_waveformat.h)0
-rw-r--r--3rdparty/portaudio/include/pa_win_wdmks.h (renamed from portaudio/include/pa_win_wdmks.h)0
-rw-r--r--3rdparty/portaudio/include/pa_win_wmme.h (renamed from portaudio/include/pa_win_wmme.h)0
-rw-r--r--3rdparty/portaudio/include/portaudio.h (renamed from portaudio/include/portaudio.h)0
-rwxr-xr-x3rdparty/portaudio/install-sh (renamed from portaudio/install-sh)0
-rw-r--r--3rdparty/portaudio/ltmain.sh (renamed from portaudio/ltmain.sh)0
-rwxr-xr-x3rdparty/portaudio/missing (renamed from portaudio/missing)0
-rw-r--r--3rdparty/portaudio/pablio/README.txt (renamed from portaudio/pablio/README.txt)0
-rw-r--r--3rdparty/portaudio/pablio/pablio.c (renamed from portaudio/pablio/pablio.c)0
-rw-r--r--3rdparty/portaudio/pablio/pablio.def (renamed from portaudio/pablio/pablio.def)0
-rw-r--r--3rdparty/portaudio/pablio/pablio.h (renamed from portaudio/pablio/pablio.h)0
-rw-r--r--3rdparty/portaudio/pablio/test_rw.c (renamed from portaudio/pablio/test_rw.c)0
-rw-r--r--3rdparty/portaudio/pablio/test_rw_echo.c (renamed from portaudio/pablio/test_rw_echo.c)0
-rw-r--r--3rdparty/portaudio/pablio/test_w_saw.c (renamed from portaudio/pablio/test_w_saw.c)0
-rw-r--r--3rdparty/portaudio/pablio/test_w_saw8.c (renamed from portaudio/pablio/test_w_saw8.c)0
-rw-r--r--3rdparty/portaudio/portaudio-2.0.pc.in (renamed from portaudio/portaudio-2.0.pc.in)0
-rw-r--r--3rdparty/portaudio/qa/loopback/README.txt (renamed from portaudio/qa/loopback/README.txt)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/audio_analyzer.c (renamed from portaudio/qa/loopback/src/audio_analyzer.c)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/audio_analyzer.h (renamed from portaudio/qa/loopback/src/audio_analyzer.h)0
-rwxr-xr-x3rdparty/portaudio/qa/loopback/src/biquad_filter.c (renamed from portaudio/qa/loopback/src/biquad_filter.c)0
-rwxr-xr-x3rdparty/portaudio/qa/loopback/src/biquad_filter.h (renamed from portaudio/qa/loopback/src/biquad_filter.h)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/paqa.c (renamed from portaudio/qa/loopback/src/paqa.c)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/paqa_tools.c (renamed from portaudio/qa/loopback/src/paqa_tools.c)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/paqa_tools.h (renamed from portaudio/qa/loopback/src/paqa_tools.h)0
-rwxr-xr-x3rdparty/portaudio/qa/loopback/src/qa_tools.h (renamed from portaudio/qa/loopback/src/qa_tools.h)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.c (renamed from portaudio/qa/loopback/src/test_audio_analyzer.c)0
-rw-r--r--3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.h (renamed from portaudio/qa/loopback/src/test_audio_analyzer.h)0
-rwxr-xr-x3rdparty/portaudio/qa/loopback/src/write_wav.c (renamed from portaudio/qa/loopback/src/write_wav.c)0
-rwxr-xr-x3rdparty/portaudio/qa/loopback/src/write_wav.h (renamed from portaudio/qa/loopback/src/write_wav.h)0
-rw-r--r--3rdparty/portaudio/qa/paqa_devs.c (renamed from portaudio/qa/paqa_devs.c)0
-rw-r--r--3rdparty/portaudio/qa/paqa_errs.c (renamed from portaudio/qa/paqa_errs.c)0
-rw-r--r--3rdparty/portaudio/qa/paqa_latency.c (renamed from portaudio/qa/paqa_latency.c)0
-rw-r--r--3rdparty/portaudio/src/SConscript (renamed from portaudio/src/SConscript)0
-rw-r--r--3rdparty/portaudio/src/common/pa_allocation.c (renamed from portaudio/src/common/pa_allocation.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_allocation.h (renamed from portaudio/src/common/pa_allocation.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_converters.c (renamed from portaudio/src/common/pa_converters.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_converters.h (renamed from portaudio/src/common/pa_converters.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_cpuload.c (renamed from portaudio/src/common/pa_cpuload.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_cpuload.h (renamed from portaudio/src/common/pa_cpuload.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_debugprint.c (renamed from portaudio/src/common/pa_debugprint.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_debugprint.h (renamed from portaudio/src/common/pa_debugprint.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_dither.c (renamed from portaudio/src/common/pa_dither.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_dither.h (renamed from portaudio/src/common/pa_dither.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_endianness.h (renamed from portaudio/src/common/pa_endianness.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_front.c (renamed from portaudio/src/common/pa_front.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_gitrevision.h (renamed from portaudio/src/common/pa_gitrevision.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_hostapi.h (renamed from portaudio/src/common/pa_hostapi.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_memorybarrier.h (renamed from portaudio/src/common/pa_memorybarrier.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_process.c (renamed from portaudio/src/common/pa_process.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_process.h (renamed from portaudio/src/common/pa_process.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_ringbuffer.c (renamed from portaudio/src/common/pa_ringbuffer.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_ringbuffer.h (renamed from portaudio/src/common/pa_ringbuffer.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_stream.c (renamed from portaudio/src/common/pa_stream.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_stream.h (renamed from portaudio/src/common/pa_stream.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_trace.c (renamed from portaudio/src/common/pa_trace.c)0
-rw-r--r--3rdparty/portaudio/src/common/pa_trace.h (renamed from portaudio/src/common/pa_trace.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_types.h (renamed from portaudio/src/common/pa_types.h)0
-rw-r--r--3rdparty/portaudio/src/common/pa_util.h (renamed from portaudio/src/common/pa_util.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c (renamed from portaudio/src/hostapi/alsa/pa_linux_alsa.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/asihpi/pa_linux_asihpi.c (renamed from portaudio/src/hostapi/asihpi/pa_linux_asihpi.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/ASIO-README.txt (renamed from portaudio/src/hostapi/asio/ASIO-README.txt)0
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/Callback_adaptation_.pdf (renamed from portaudio/src/hostapi/asio/Callback_adaptation_.pdf)bin50527 -> 50527 bytes
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/Pa_ASIO.pdf (renamed from portaudio/src/hostapi/asio/Pa_ASIO.pdf)bin50778 -> 50778 bytes
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp (renamed from portaudio/src/hostapi/asio/iasiothiscallresolver.cpp)0
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.h (renamed from portaudio/src/hostapi/asio/iasiothiscallresolver.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp (renamed from portaudio/src/hostapi/asio/pa_asio.cpp)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/notes.txt (renamed from portaudio/src/hostapi/coreaudio/notes.txt)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h (renamed from portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c (renamed from portaudio/src/hostapi/dsound/pa_win_ds.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c (renamed from portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h (renamed from portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/jack/pa_jack.c (renamed from portaudio/src/hostapi/jack/pa_jack.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/oss/low_latency_tip.txt (renamed from portaudio/src/hostapi/oss/low_latency_tip.txt)bin3111 -> 3111 bytes
-rw-r--r--3rdparty/portaudio/src/hostapi/oss/pa_unix_oss.c (renamed from portaudio/src/hostapi/oss/pa_unix_oss.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/oss/recplay.c (renamed from portaudio/src/hostapi/oss/recplay.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/skeleton/README.txt (renamed from portaudio/src/hostapi/skeleton/README.txt)0
-rw-r--r--3rdparty/portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c (renamed from portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/audioclient.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/audioclient.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ks.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ks.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksguid.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ksguid.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkey.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/propkey.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propsys.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/propsys.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sal.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/sal.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h (renamed from portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c (renamed from portaudio/src/hostapi/wasapi/pa_win_wasapi.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wasapi/readme.txt (renamed from portaudio/src/hostapi/wasapi/readme.txt)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c (renamed from portaudio/src/hostapi/wdmks/pa_win_wdmks.c)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wdmks/readme.txt (renamed from portaudio/src/hostapi/wdmks/readme.txt)0
-rw-r--r--3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c (renamed from portaudio/src/hostapi/wmme/pa_win_wmme.c)0
-rw-r--r--3rdparty/portaudio/src/os/unix/pa_unix_hostapis.c (renamed from portaudio/src/os/unix/pa_unix_hostapis.c)0
-rw-r--r--3rdparty/portaudio/src/os/unix/pa_unix_util.c (renamed from portaudio/src/os/unix/pa_unix_util.c)0
-rw-r--r--3rdparty/portaudio/src/os/unix/pa_unix_util.h (renamed from portaudio/src/os/unix/pa_unix_util.h)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_coinitialize.c (renamed from portaudio/src/os/win/pa_win_coinitialize.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_coinitialize.h (renamed from portaudio/src/os/win/pa_win_coinitialize.h)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_hostapis.c (renamed from portaudio/src/os/win/pa_win_hostapis.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_util.c (renamed from portaudio/src/os/win/pa_win_util.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_waveformat.c (renamed from portaudio/src/os/win/pa_win_waveformat.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c (renamed from portaudio/src/os/win/pa_win_wdmks_utils.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.h (renamed from portaudio/src/os/win/pa_win_wdmks_utils.h)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_x86_plain_converters.c (renamed from portaudio/src/os/win/pa_x86_plain_converters.c)0
-rw-r--r--3rdparty/portaudio/src/os/win/pa_x86_plain_converters.h (renamed from portaudio/src/os/win/pa_x86_plain_converters.h)0
-rw-r--r--3rdparty/portaudio/test/CMakeLists.txt (renamed from portaudio/test/CMakeLists.txt)0
-rw-r--r--3rdparty/portaudio/test/README.txt (renamed from portaudio/test/README.txt)0
-rw-r--r--3rdparty/portaudio/test/pa_minlat.c (renamed from portaudio/test/pa_minlat.c)0
-rw-r--r--3rdparty/portaudio/test/patest1.c (renamed from portaudio/test/patest1.c)0
-rw-r--r--3rdparty/portaudio/test/patest_buffer.c (renamed from portaudio/test/patest_buffer.c)0
-rw-r--r--3rdparty/portaudio/test/patest_callbackstop.c (renamed from portaudio/test/patest_callbackstop.c)0
-rw-r--r--3rdparty/portaudio/test/patest_clip.c (renamed from portaudio/test/patest_clip.c)0
-rw-r--r--3rdparty/portaudio/test/patest_converters.c (renamed from portaudio/test/patest_converters.c)0
-rw-r--r--3rdparty/portaudio/test/patest_dither.c (renamed from portaudio/test/patest_dither.c)0
-rw-r--r--3rdparty/portaudio/test/patest_dsound_find_best_latency_params.c (renamed from portaudio/test/patest_dsound_find_best_latency_params.c)0
-rw-r--r--3rdparty/portaudio/test/patest_dsound_low_level_latency_params.c (renamed from portaudio/test/patest_dsound_low_level_latency_params.c)0
-rw-r--r--3rdparty/portaudio/test/patest_dsound_surround.c (renamed from portaudio/test/patest_dsound_surround.c)0
-rw-r--r--3rdparty/portaudio/test/patest_hang.c (renamed from portaudio/test/patest_hang.c)0
-rw-r--r--3rdparty/portaudio/test/patest_in_overflow.c (renamed from portaudio/test/patest_in_overflow.c)0
-rw-r--r--3rdparty/portaudio/test/patest_jack_wasapi.c (renamed from portaudio/test/patest_jack_wasapi.c)0
-rw-r--r--3rdparty/portaudio/test/patest_latency.c (renamed from portaudio/test/patest_latency.c)0
-rw-r--r--3rdparty/portaudio/test/patest_leftright.c (renamed from portaudio/test/patest_leftright.c)0
-rw-r--r--3rdparty/portaudio/test/patest_longsine.c (renamed from portaudio/test/patest_longsine.c)0
-rw-r--r--3rdparty/portaudio/test/patest_many.c (renamed from portaudio/test/patest_many.c)0
-rw-r--r--3rdparty/portaudio/test/patest_maxsines.c (renamed from portaudio/test/patest_maxsines.c)0
-rw-r--r--3rdparty/portaudio/test/patest_mono.c (renamed from portaudio/test/patest_mono.c)0
-rw-r--r--3rdparty/portaudio/test/patest_multi_sine.c (renamed from portaudio/test/patest_multi_sine.c)0
-rw-r--r--3rdparty/portaudio/test/patest_out_underflow.c (renamed from portaudio/test/patest_out_underflow.c)0
-rw-r--r--3rdparty/portaudio/test/patest_prime.c (renamed from portaudio/test/patest_prime.c)0
-rw-r--r--3rdparty/portaudio/test/patest_read_record.c (renamed from portaudio/test/patest_read_record.c)0
-rw-r--r--3rdparty/portaudio/test/patest_ringmix.c (renamed from portaudio/test/patest_ringmix.c)0
-rw-r--r--3rdparty/portaudio/test/patest_sine8.c (renamed from portaudio/test/patest_sine8.c)0
-rw-r--r--3rdparty/portaudio/test/patest_sine_channelmaps.c (renamed from portaudio/test/patest_sine_channelmaps.c)0
-rw-r--r--3rdparty/portaudio/test/patest_sine_formats.c (renamed from portaudio/test/patest_sine_formats.c)0
-rw-r--r--3rdparty/portaudio/test/patest_sine_srate.c (renamed from portaudio/test/patest_sine_srate.c)0
-rw-r--r--3rdparty/portaudio/test/patest_sine_time.c (renamed from portaudio/test/patest_sine_time.c)0
-rw-r--r--3rdparty/portaudio/test/patest_start_stop.c (renamed from portaudio/test/patest_start_stop.c)0
-rw-r--r--3rdparty/portaudio/test/patest_stop.c (renamed from portaudio/test/patest_stop.c)0
-rw-r--r--3rdparty/portaudio/test/patest_stop_playout.c (renamed from portaudio/test/patest_stop_playout.c)0
-rw-r--r--3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.c (renamed from portaudio/test/patest_suggested_vs_streaminfo_latency.c)0
-rw-r--r--3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.py (renamed from portaudio/test/patest_suggested_vs_streaminfo_latency.py)0
-rw-r--r--3rdparty/portaudio/test/patest_sync.c (renamed from portaudio/test/patest_sync.c)0
-rw-r--r--3rdparty/portaudio/test/patest_timing.c (renamed from portaudio/test/patest_timing.c)0
-rw-r--r--3rdparty/portaudio/test/patest_toomanysines.c (renamed from portaudio/test/patest_toomanysines.c)0
-rw-r--r--3rdparty/portaudio/test/patest_two_rates.c (renamed from portaudio/test/patest_two_rates.c)0
-rw-r--r--3rdparty/portaudio/test/patest_underflow.c (renamed from portaudio/test/patest_underflow.c)0
-rw-r--r--3rdparty/portaudio/test/patest_unplug.c (renamed from portaudio/test/patest_unplug.c)0
-rw-r--r--3rdparty/portaudio/test/patest_wire.c (renamed from portaudio/test/patest_wire.c)0
-rw-r--r--3rdparty/portaudio/test/patest_wmme_find_best_latency_params.c (renamed from portaudio/test/patest_wmme_find_best_latency_params.c)0
-rw-r--r--3rdparty/portaudio/test/patest_wmme_low_level_latency_params.c (renamed from portaudio/test/patest_wmme_low_level_latency_params.c)0
-rw-r--r--3rdparty/portaudio/test/patest_write_stop.c (renamed from portaudio/test/patest_write_stop.c)0
-rw-r--r--3rdparty/portaudio/test/patest_write_stop_hang_illegal.c (renamed from portaudio/test/patest_write_stop_hang_illegal.c)0
-rwxr-xr-x3rdparty/portaudio/update_gitrevision.sh (renamed from portaudio/update_gitrevision.sh)0
-rw-r--r--CMakeLists.txt19
-rw-r--r--portaudio/bindings/cpp/build/gnu/Makefile.in106
-rw-r--r--portaudio/bindings/cpp/build/gnu/OUT_OF_DATE0
-rw-r--r--portaudio/bindings/cpp/build/gnu/aclocal.m457
-rw-r--r--portaudio/bindings/cpp/build/gnu/config.guess1308
-rw-r--r--portaudio/bindings/cpp/build/gnu/config.sub1505
-rw-r--r--portaudio/bindings/cpp/build/gnu/configure4297
-rw-r--r--portaudio/bindings/cpp/build/gnu/configure.ac214
-rw-r--r--portaudio/bindings/cpp/build/gnu/install-sh251
-rw-r--r--portaudio/bindings/cpp/build/vc6/devs_example.dsp248
-rw-r--r--portaudio/bindings/cpp/build/vc6/devs_example.dsw44
-rw-r--r--portaudio/bindings/cpp/build/vc6/sine_example.dsp252
-rw-r--r--portaudio/bindings/cpp/build/vc6/sine_example.dsw44
-rw-r--r--portaudio/bindings/cpp/build/vc6/static_library.dsp395
-rw-r--r--portaudio/bindings/cpp/build/vc6/static_library.dsw29
-rw-r--r--portaudio/bindings/cpp/build/vc7/OUT_OF_DATE0
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/devs_example.sln30
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/devs_example.vcproj195
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/sine_example.sln30
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/sine_example.vcproj327
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/static_library.sln21
-rw-r--r--portaudio/bindings/cpp/build/vc7_1/static_library.vcproj218
-rw-r--r--portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.sln26
-rw-r--r--portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcproj198
-rw-r--r--portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcxproj174
-rw-r--r--portaudio/build/msvc/portaudio.def58
-rw-r--r--portaudio/build/msvc/portaudio.dsp269
-rw-r--r--portaudio/build/msvc/portaudio.dsw29
-rw-r--r--portaudio/build/msvc/portaudio.sln32
-rw-r--r--portaudio/build/msvc/portaudio.vcproj1932
-rw-r--r--portaudio/build/msvc/readme.txt112
-rw-r--r--portaudio/build/scons/SConscript_common30
-rw-r--r--portaudio/build/scons/SConscript_opts91
617 files changed, 48528 insertions, 12528 deletions
diff --git a/3rdparty/plibsys/.codedocs b/3rdparty/plibsys/.codedocs
new file mode 100644
index 0000000..1811d03
--- /dev/null
+++ b/3rdparty/plibsys/.codedocs
@@ -0,0 +1,53 @@
+# Optional project name, if left empty the GitHub repository name will be used.
+PROJECT_NAME = plibsys
+
+# One or more directories and files that contain example code to be included.
+EXAMPLE_PATH =
+
+# One or more directories and files to exclude from documentation generation.
+# Use relative paths with respect to the repository root directory.
+EXCLUDE =
+
+# One or more wildcard patterns to exclude files and directories from document
+# generation.
+EXCLUDE_PATTERNS = pcryptohash-*.* \
+ ptree-*.* \
+ plibsys.h \
+ *-private.h \
+ CMakeLists.txt
+
+# One or more symbols to exclude from document generation. Symbols can be
+# namespaces, classes, or functions.
+EXCLUDE_SYMBOLS = __has_attribute \
+ __has_builtin
+
+# Override the default parser (language) used for each file extension.
+EXTENSION_MAPPING =
+
+# Set the wildcard patterns used to filter out the source-files.
+# If left blank the default is:
+# *.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl,
+# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php,
+# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox, *.py,
+# *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
+FILE_PATTERNS = *.h
+
+# Hide undocumented class members.
+HIDE_UNDOC_MEMBERS = NO
+
+# Hide undocumented classes.
+HIDE_UNDOC_CLASSES = NO
+
+# Specify a markdown page whose contents should be used as the main page
+# (index.html). This will override a page marked as \mainpage. For example, a
+# README.md file usually serves as a useful main page.
+USE_MDFILE_AS_MAINPAGE = README.md
+
+# Specify external repository to link documentation with.
+# This is similar to Doxygen's TAGFILES option, but will automatically link to
+# tags of other repositories already using CodeDocs. List each repository to
+# link with by giving its location in the form of owner/repository.
+# For example:
+# TAGLINKS = doxygen/doxygen CodeDocs/osg
+# Note: these repositories must already be built on CodeDocs.
+TAGLINKS =
diff --git a/3rdparty/plibsys/.gear/plibsys.spec b/3rdparty/plibsys/.gear/plibsys.spec
new file mode 100644
index 0000000..0b86e24
--- /dev/null
+++ b/3rdparty/plibsys/.gear/plibsys.spec
@@ -0,0 +1,104 @@
+%define soname 0
+
+Name: plibsys
+Version: 0.0.4
+Release: alt1
+
+Summary: Highly portable C system library
+License: MIT
+Group: Development/C
+
+Url: https://github.com/saprykin/plibsys
+Source: %name-%version.tar
+
+BuildPreReq: gcc-c++ cmake rpm-macros-cmake doxygen
+
+%description
+plibsys is a cross-platform system C library with some helpful routines.
+It has zero third-party dependencies and uses only native system calls.
+
+plibsys provides:
+
+Platform independent data types
+Threads
+Mutexes
+Condition variables
+Read-write locks
+System-wide semaphores
+System-wide shared memory
+Optimized spinlock
+Atomic operations
+Socket support (UDP, TCP, SCTP) with IPv4 and IPv6
+Hash functions: MD5, SHA-1, SHA-2, SHA-3, GOST (R 34.11-94)
+Binary trees: BST, red-black, AVL
+INI file parser
+High resolution time profiler
+Files and directories
+Shared library loading
+Useful routines for linked lists, strings, hash tables
+Macros for CPU architecture, OS and compiler detection
+Macros for variable arguments
+
+%package -n lib%name%soname
+Summary: %summary
+Group: System/Libraries
+
+%description -n lib%name%soname
+Highly portable C system library: threads and synchronization primitives,
+sockets (TCP, UDP, SCTP), IPv4 and IPv6, IPC, hash functions (MD5, SHA-1,
+SHA-2, SHA-3, GOST), binary trees (RB, AVL) and more.
+Native code performance.
+
+%package -n lib%name-devel
+Summary: %summary
+Group: Development/C
+
+%description -n lib%name-devel
+Highly portable C system library: threads and synchronization primitives,
+sockets (TCP, UDP, SCTP), IPv4 and IPv6, IPC, hash functions (MD5, SHA-1,
+SHA-2, SHA-3, GOST), binary trees (RB, AVL) and more.
+Native code performance.
+
+This package provides headers to build software using %name.
+
+%package -n %name-doc
+Summary: %name docs
+Group: Development/Documentation
+
+%description -n %name-doc
+HTML API documentation for the plibsys library
+
+%prep
+%setup
+
+%build
+%cmake_insource \
+ -DCMAKE_INSTALL_LIBDIR=%_lib \
+ -DPLIBSYS_BUILD_STATIC=OFF \
+ -DPLIBSYS_TESTS=OFF \
+ -DPLIBSYS_BUILD_DOC=ON \
+ -DCMAKE_SKIP_RPATH=ON \
+ #
+%make_build
+
+%install
+%makeinstall_std
+rm -rf %buildroot%_defaultdocdir/*
+
+%files -n lib%name%soname
+%doc AUTHORS COPYING NEWS README.md
+%_libdir/*.so.*
+
+%files -n lib%name-devel
+%_includedir/*
+%_libdir/*.so
+
+%files -n %name-doc
+%doc doc/html/*
+
+%changelog
+* Sat May 26 2018 Alexander Saprykin <saprykin.spb@gmail.com> 0.0.4-alt1
+- Update to version 0.0.4
+* Tue Sep 19 2017 Michael Shigorin <mike@altlinux.org> 0.0.3-alt1
+- Initial build
+
diff --git a/3rdparty/plibsys/.gear/rules b/3rdparty/plibsys/.gear/rules
new file mode 100644
index 0000000..9ae2212
--- /dev/null
+++ b/3rdparty/plibsys/.gear/rules
@@ -0,0 +1,2 @@
+tar: .
+spec: .gear/plibsys.spec
diff --git a/3rdparty/plibsys/.travis.yml b/3rdparty/plibsys/.travis.yml
new file mode 100644
index 0000000..55641b1
--- /dev/null
+++ b/3rdparty/plibsys/.travis.yml
@@ -0,0 +1,171 @@
+env:
+ global:
+ # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
+ # via the "travis encrypt" command using the project repo's public key
+ - secure: "Jw8Q8kFOfP4kiicGpZX496H0Hhi2+PzQ5wSpSJ/+e4rdQ/PnQuCvJfyAJ/k6+7BmgeS80T4sfK5xB5nX3yZG1FA4VE4kXuppJlVSwTZer0dlbbK3rvdSChBf5/Nnfjsj/Ch2SjjwhOt8zhjVutWuT2wz9RwOO39heQf3KFb4qbaVbnaBRTiGYJ+6D/28dX5foMehTohtcN1WKUZULum4cP8tqdn2+0cH+afwDwODap4v8brEW8HifS4QGDejAE7zR9fr3BaJl2m9s8art5lGzoK6Qaf2SS8WBW0MVzv2CP6zfsLUmPm3WijGUzAIPPi5GRFSy7O0GdkhHziMof1vyE3irXLSFlhg5g76lHEI2vpE6m+/PQ4I9jp7+oBT0N4SadgiXReXxewAZRrInCOstNN/mWIF0C0r1gWvPS3uM5u4PfGRa72GJ39SWmDvQqmOHOy15ZGA2eyw8piLAVkVJKvhufNfwEULITHE9xQXCV3e0YZrNIjMofuRszz7yLHEXlhwJxG++E4h0uCKnCqLTcLas8sBcRw98H/k9s8yZR3u9v0F0qqX/wus2TvfMjsfOqMm9MyqTXexpsMiODiN0a8zpdhufDlyxgr+2S96NlER7Iu0aRPBVgfDP2COPxmVW4ZwDpZYxK6iANeiYVuQGHccDHjZRyiSCG2c47EKV14="
+ - COVERITY_SCAN_PROJECT_NAME="saprykin/plibsys"
+ - COVERITY_SCAN_BRANCH_PATTERN="coverity_scan"
+ - COVERITY_SCAN_NOTIFICATION_EMAIL="saprykin.spb@gmail.com"
+ - COVERITY_SCAN_BUILD_COMMAND="make"
+
+language: generic
+dist: xenial
+
+matrix:
+ include:
+ # Code coverage build
+ - os: linux
+ addons: { apt: { packages: [lcov] } }
+ env: CC=gcc CXX=g++ GCOV=gcov USE_GCOV=1
+ # Linux x64 builds (GCC)
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-4.9, g++-4.9] } }
+ env: CC=gcc-4.9 CXX=g++-4.9 ARCH=64 USE_COVERITY=1
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-5, g++-5] } }
+ env: CC=gcc-5 CXX=g++-5 ARCH=64
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-6, g++-6] } }
+ env: CC=gcc-6 CXX=g++-6 ARCH=64
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-7, g++-7] } }
+ env: CC=gcc-7 CXX=g++-7 ARCH=64
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-8, g++-8] } }
+ env: CC=gcc-8 CXX=g++-8 ARCH=64
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-9, g++-9] } }
+ env: CC=gcc-9 CXX=g++-9 ARCH=64
+ # IBM Power builds (GCC)
+ - os: linux
+ arch: ppc64le
+ env: CC=gcc CXX=g++
+ # IBM Z builds (GCC)
+ - os: linux
+ arch: s390x
+ env: CC=gcc CXX=g++
+ # Amazon Graviton-2 ARM
+ - os: linux
+ arch: arm64
+ env: CC=gcc CXX=g++
+ # Linux x86 builds (GCC)
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-4.9, g++-4.9, gcc-multilib, g++-multilib, gcc-4.9-multilib, g++-4.9-multilib, linux-libc-dev] } }
+ env: CC=gcc-4.9 CXX=g++-4.9 ARCH=32
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-5, g++-5, gcc-multilib, g++-multilib, gcc-5-multilib, g++-5-multilib, linux-libc-dev] } }
+ env: CC=gcc-5 CXX=g++-5 ARCH=32
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-6, g++-6, gcc-multilib, g++-multilib, gcc-6-multilib, g++-6-multilib, linux-libc-dev] } }
+ env: CC=gcc-6 CXX=g++-6 ARCH=32
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-7, g++-7, gcc-multilib, g++-multilib, gcc-7-multilib, g++-7-multilib, linux-libc-dev] } }
+ env: CC=gcc-7 CXX=g++-7 ARCH=32
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-8, g++-8, gcc-multilib, g++-multilib, gcc-8-multilib, g++-8-multilib, linux-libc-dev] } }
+ env: CC=gcc-8 CXX=g++-8 ARCH=32
+ - os: linux
+ addons: { apt: { sources: ubuntu-toolchain-r-test, packages: [gcc-9, g++-9, gcc-multilib, g++-multilib, gcc-9-multilib, g++-9-multilib, linux-libc-dev] } }
+ env: CC=gcc-9 CXX=g++-9 ARCH=32
+ # Linux x64 builds (Clang)
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-trusty-3.6], packages: [clang-3.6, libc++-dev] } }
+ env: CC=clang-3.6 CXX=clang++-3.6
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-trusty-3.7], packages: [clang-3.7, libc++-dev] } }
+ env: CC=clang-3.7 CXX=clang++-3.7
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-3.8], packages: [clang-3.8, libc++-dev] } }
+ env: CC=clang-3.8 CXX=clang++-3.8
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-3.9], packages: [clang-3.9, libc++-dev] } }
+ env: CC=clang-3.9 CXX=clang++-3.9
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-4.0], packages: [clang-4.0, libc++-dev] } }
+ env: CC=clang-4.0 CXX=clang++-4.0
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-5.0], packages: [clang-5.0, libc++-dev] } }
+ env: CC=clang-5.0 CXX=clang++-5.0
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-6.0], packages: [clang-6.0, libc++-dev] } }
+ env: CC=clang-6.0 CXX=clang++-6.0
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-7], packages: [clang-7, libc++-dev] } }
+ env: CC=clang-7 CXX=clang++-7
+ - os: linux
+ addons: { apt: { sources: [ubuntu-toolchain-r-test, llvm-toolchain-xenial-8], packages: [clang-8, libc++-dev] } }
+ env: CC=clang-8 CXX=clang++-8
+ # macOS builds (GCC)
+ - os: osx
+ osx_image: xcode10.2
+ env: FORMULA=gcc@6 CC=gcc-6 CXX=g++-6
+ - os: osx
+ osx_image: xcode10.2
+ env: FORMULA=gcc@7 CC=gcc-7 CXX=g++-7
+ - os: osx
+ osx_image: xcode10.2
+ env: FORMULA=gcc@8 CC=gcc-8 CXX=g++-8
+ - os: osx
+ osx_image: xcode10.2
+ env: FORMULA=gcc@9 CC=gcc-9 CXX=g++-9
+ # macOS builds (Clang)
+ - os: osx
+ osx_image: xcode6.4
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode7.3
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode8.3
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode9.2
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode9.4
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode10.3
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode11.3
+ env: CC=clang CXX=clang++
+ - os: osx
+ osx_image: xcode12
+ env: CC=clang CXX=clang++
+
+branches:
+ only:
+ - master
+ - coverity_scan
+
+before_install:
+ - if [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]; then export USE_GCOV="" ; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && (! [[ -z ${FORMULA+x} ]] || ! [[ -z ${USE_GCOV} ]]) ; then brew update ; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && [[ "${USE_GCOV}" == "1" ]]; then brew install lcov ; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && ! [[ -z ${FORMULA+x} ]]; then brew cask uninstall oclint || true; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && ! [[ -z ${FORMULA+x} ]]; then brew unlink gcc || true; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && ! [[ -z ${FORMULA+x} ]]; then brew unlink ${FORMULA} || true; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && ! [[ -z ${FORMULA+x} ]]; then brew install ${FORMULA}; fi
+ - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && ! [[ -z ${FORMULA+x} ]]; then brew link ${FORMULA}; fi
+
+before_script:
+ - mkdir ./plibsys-build
+ - cd ./plibsys-build
+ - ${CC} --version
+ - ${CC} -dM -E - < /dev/null
+ - ${CXX} --version
+ - ${CXX} -dM -E -x c++ - < /dev/null
+ - if ! [[ -z ${ARCH+x} ]]; then export CMAKE_ARCH_PARAM=-m${ARCH} ; fi
+ - if [[ "${USE_GCOV}" == "1" ]]; then cmake -DPLIBSYS_COVERAGE=ON -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_FLAGS=${CMAKE_ARCH_PARAM} -DCMAKE_CXX_FLAGS=${CMAKE_ARCH_PARAM} .. ; fi
+ - if ! [[ "${USE_GCOV}" == "1" ]]; then cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_FLAGS=${CMAKE_ARCH_PARAM} -DCMAKE_CXX_FLAGS=${CMAKE_ARCH_PARAM} .. ; fi
+ - if [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]] && [[ "${USE_COVERITY}" == "1" ]]; then export COVERITY_SCAN_BUILD_COMMAND_PREPEND="cov-configure --comptype gcc --compiler ${CC} --template" ; fi
+ - if [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]] && [[ "${USE_COVERITY}" == "1" ]]; then curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash || true ; fi
+
+script:
+ - make -j 2
+ - if [[ "${TRAVIS_BRANCH}" != "coverity_scan" ]]; then ctest --output-on-failure -V -C Release; fi
+
+after_success:
+ - if [[ "${USE_GCOV}" == "1" ]]; then lcov --gcov-tool ${GCOV} --directory . --capture --output-file coverage.info ; fi
+ - if [[ "${USE_GCOV}" == "1" ]]; then bash <(curl -s https://codecov.io/bash) -x ${GCOV} ; fi
diff --git a/3rdparty/plibsys/3dparty/scosv/FSU-threads-3.14.tgz b/3rdparty/plibsys/3dparty/scosv/FSU-threads-3.14.tgz
new file mode 100644
index 0000000..ee9a9d0
--- /dev/null
+++ b/3rdparty/plibsys/3dparty/scosv/FSU-threads-3.14.tgz
Binary files differ
diff --git a/3rdparty/plibsys/AUTHORS b/3rdparty/plibsys/AUTHORS
new file mode 100644
index 0000000..fbdf37a
--- /dev/null
+++ b/3rdparty/plibsys/AUTHORS
@@ -0,0 +1,2 @@
+Alexander Saprykin <saprykin.spb@gmail.com>
+Jean-Damien Durand <jeandamiendurand@free.fr>
diff --git a/3rdparty/plibsys/CMakeLists.txt b/3rdparty/plibsys/CMakeLists.txt
new file mode 100644
index 0000000..8a47585
--- /dev/null
+++ b/3rdparty/plibsys/CMakeLists.txt
@@ -0,0 +1,93 @@
+# The MIT License
+#
+# Copyright (C) 2018-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+set (CMAKE_LEGACY_CYGWIN_WIN32 0)
+
+cmake_minimum_required (VERSION 2.8.0)
+project (plibsys C)
+
+set (PLIBSYS_VERSION_MAJOR 0)
+set (PLIBSYS_VERSION_MINOR 0)
+set (PLIBSYS_VERSION_PATCH 4)
+set (PLIBSYS_VERSION_NUM 0x000004)
+set (PLIBSYS_VERSION ${PLIBSYS_VERSION_MAJOR}.${PLIBSYS_VERSION_MINOR}.${PLIBSYS_VERSION_PATCH})
+set (PLIBSYS_SOVERSION ${PLIBSYS_VERSION_MAJOR})
+set (VERSION ${PLIBSYS_VERSION})
+
+set (top_srcdir ${PROJECT_SOURCE_DIR})
+
+option (PLIBSYS_TESTS "Build unit tests" OFF)
+option (PLIBSYS_BUILD_STATIC "Also build static version of the library" ON)
+option (PLIBSYS_COVERAGE "Enable gcov coverage (GCC and Clang)" OFF)
+option (PLIBSYS_VISIBILITY "Use explicit symbols visibility if possible" OFF)
+option (PLIBSYS_BUILD_DOC "Enable building HTML documentation" OFF)
+
+if (NOT CMAKE_BUILD_TYPE)
+ set (CMAKE_BUILD_TYPE "Debug")
+endif()
+
+subdirs (src)
+
+if (PLIBSYS_TESTS)
+ enable_testing ()
+ subdirs (tests)
+endif()
+
+if (PLIBSYS_BUILD_DOC)
+ find_package (Doxygen)
+
+ if (DOXYGEN_FOUND)
+ configure_file (${PROJECT_SOURCE_DIR}/Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile)
+
+ add_custom_target (doc ALL
+ COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
+ WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
+ COMMENT "Generating API documentation with Doxygen"
+ VERBATIM
+ )
+
+ install (DIRECTORY ${PROJECT_BINARY_DIR}/doc/html DESTINATION share/doc)
+ endif()
+endif()
+
+set (CPACK_PACKAGE_NAME ${PROJECT_NAME}-installer)
+set (CPACK_PACKAGE_VENDOR "Alexander Saprykin")
+set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME} - System routines library")
+set (CPACK_PACKAGE_VERSION_MAJOR ${PLIBSYS_VERSION_MAJOR})
+set (CPACK_PACKAGE_VERSION_MINOR ${PLIBSYS_VERSION_MINOR})
+set (CPACK_PACKAGE_VERSION_PATCH ${PLIBSYS_VERSION_PATCH})
+set (CPACK_PACKAGE_VERSION ${PLIBSYS_VERSION})
+set (CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME}-${CPACK_PACKAGE_VERSION})
+set (CPACK_COMPONENTS_ALL Core)
+set (CPACK_COMPONENT_CORE_DISPLAY_NAME "Core components")
+set (CPACK_COMPONENT_CORE_DESCRIPTION "Core library with headers")
+set (CPACK_COMPONENT_CORE_REQUIRED TRUE)
+
+if (WIN32 AND NOT UNIX)
+ set (CPACK_NSIS_DISPLAY_NAME ${PROJECT_NAME})
+elseif (UNIX)
+ set (CPACK_GENERATOR STGZ)
+endif()
+
+include (CPack)
diff --git a/3rdparty/plibsys/COPYING b/3rdparty/plibsys/COPYING
new file mode 100644
index 0000000..09d2d2e
--- /dev/null
+++ b/3rdparty/plibsys/COPYING
@@ -0,0 +1,20 @@
+The MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/plibsys/Doxyfile.in b/3rdparty/plibsys/Doxyfile.in
new file mode 100644
index 0000000..0c59d23
--- /dev/null
+++ b/3rdparty/plibsys/Doxyfile.in
@@ -0,0 +1,180 @@
+# Doxyfile 0.0.1
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = plibsys
+PROJECT_NUMBER = @VERSION@
+OUTPUT_DIRECTORY = doc
+OUTPUT_LANGUAGE = English
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+STRIP_CODE_COMMENTS = YES
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+VERBATIM_HEADERS = YES
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = YES
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = YES
+SHOW_USED_FILES = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = YES
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_FORMAT =
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = @top_srcdir@/src
+FILE_PATTERNS = *.h
+RECURSIVE = YES
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS = Makefile.* \
+ pcryptohash-*.* \
+ ptree-*.* \
+ plibsys.h \
+ *-private.h \
+ CMakeLists.txt
+
+EXCLUDE_SYMBOLS = __has_attribute \
+ __has_builtin
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+GENERATE_HTMLHELP = NO
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+COMPACT_LATEX = NO
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3plibsys
+MAN_LINKS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = "P_BEGIN_DECLS=" \
+ "P_END_DECLS=" \
+ "DOXYGEN_SHOULD_SKIP_THIS" \
+ "DOXYGEN"
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+TEMPLATE_RELATIONS = YES
+HIDE_UNDOC_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DOT_PATH =
+DOTFILE_DIRS =
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/3rdparty/plibsys/NEWS b/3rdparty/plibsys/NEWS
new file mode 100644
index 0000000..fb79bde
--- /dev/null
+++ b/3rdparty/plibsys/NEWS
@@ -0,0 +1,122 @@
+Changes in plibsys 0.0.4
+========================
+
+* Switch to MIT license from LGPLv2+ (#71)
+* Replace Boost test framework with own one (#56)
+* Add visibility support for APIs
+* Add Debian package (in separate branch) (#54)
+* Add gear package (ALT Linux)
+* Add Conan packages
+* Add option to generate Doxygen documentation
+
+* New supported platforms and compilers:
+ BlackBerry 10 (AArch32, x86)
+ Cray Linux Environment
+ AmigaOS 4.1 (PPC) (#59)
+ Android (x86, x64, AArch32, AArch64) (#69)
+ iOS, tvOS, watchOS (x86, x64, AArch32, AArch64) (#70)
+ PGI (x64) compiler on macOS
+
+* New API
+ Macros for variable arguments
+
+* AppVeyor
+ Add Visual Studio 2017 builds (#53)
+ Build tests for Watcom compiler (#57)
+
+* Travis
+ Add GCC 7.x builds (#48)
+ Add Clang 4.0 and 5.0 builds
+ Add MinGW 7.1.x (x64) builds
+ Update MinGW builds to 6.3.x (x64)
+ Add Xcode 8.3 and 9.1 builds
+
+* Fixes
+ Do not use deprecated readdir_r() with glibc >= 2.24
+ Use CryptoPro S-box instead of testing in GOST hashing
+ Initialize POSIX semaphore with given value in create mode
+ Setup proper SONAME value (not the same as API version)
+
+Changes in plibsys 0.0.3
+========================
+
+* Introduce models for shared library loading (#37)
+* HP-UX shared library loading model (#39)
+* Use lldiv() to improve time profiler accuracy
+* Better error handling for shared library loading (#40)
+* CPU architecture detection macros (#44)
+* Prefer clock_nanosleep() over nanosleep() if available (#47)
+
+* New supported platforms and compilers:
+ BeOS on x86 (GCC)
+ OS/2 on x86 (GCC + kLIBC) (#41)
+ PGI (x64) compiler on Linux
+ PGI (x86) compiler on macOS
+
+* New API
+ Add routine to check for IPv6 support
+ Add routine to check if library loading is reference counted
+ Add detection of number of the CPU cores (#43)
+
+* AppVeyor
+ MSYS2 build is disabled due to a bug in CMake package
+
+* Travis
+ Correct Brew formula names for GCC on macOS
+ Update Xcode8 image to 8.3 version
+ Fix Coverity scan
+
+* Fixes
+ Do not use poll() on macOS as it can be broken
+ Do not treat some non-UNIX systems as UNIX (#42)
+ Always define P_SOCKET_FAMILY_INET6
+ Use PLIBSYS_PLATFORM_LDFLAGS to perform system checks
+ Prevent Doxygen from generating duplicate macros (#46)
+
+Changes in plibsys 0.0.2
+========================
+
+* Rename project to lower case letters
+* Move to LGPL license
+* Print routine names in warning and error output
+* Add CMake option PLIBSYS_TESTS to disable tests completely
+* Add ability to use general model for read-write locks explicitly
+
+* New API:
+ New hashing algorithms: SHA-256/224, SHA-512/384, SHA-3
+ Add routines to get and set last native error codes
+
+* New supported platforms and compilers:
+ OpenVMS on Alpha and IA64 (DEC C)
+ Tru64 on Alpha (Compaq, GCC)
+ Linux on PPC64le (IBM XL C, GCC)
+ Syllable (GCC)
+
+* AppVeyor:
+ Add parallel builds for Microsoft compilers
+ Add LLVM (x64) build
+ Add MinGW 4.9, 5.4 and 6.2 builds
+ Add MSYS64 (x64) build
+ Add MSYS64 (MinGW x86) build
+ Add Cygwin (x86, x64) builds
+ Add OpenWatcom 1.9 build
+
+* Travis:
+ Move to container-based builds
+ Add GCC 4.9, 5.4 and 6.x builds (x86, x64) for Linux
+ Add Clang 3.6, 3.7 and 3.8 builds (x64) for Linux
+ Add GCC 4.9, 5.4 and 6.x builds (x64) for macOS
+ Add Xcode 6.4, 7.3 and 8 builds (x64) for macOS
+
+* Boost:
+ Backport changes from 1.62 to fix warnings with GCC 6.x
+
+* Fixes:
+ Fix race condition on Solaris when creating a TLS key
+ Fix potential leak on SCO when creating a TLS key
+ Fix building tests in QNX
+
+Changes in plibsys 0.0.1
+========================
+
+* Initial release
diff --git a/3rdparty/plibsys/README.md b/3rdparty/plibsys/README.md
new file mode 100644
index 0000000..a25b247
--- /dev/null
+++ b/3rdparty/plibsys/README.md
@@ -0,0 +1,115 @@
+
+[![](https://api.travis-ci.org/saprykin/plibsys.svg?branch=master)](https://travis-ci.org/saprykin/plibsys)
+[![](https://ci.appveyor.com/api/projects/status/github/saprykin/plibsys?branch=appveyor_test&svg=true)](https://ci.appveyor.com/project/saprykin/plibsys)
+[![](https://scan.coverity.com/projects/8333/badge.svg)](https://scan.coverity.com/projects/saprykin-plibsys)
+[![](https://codecov.io/gh/saprykin/plibsys/branch/master/graph/badge.svg)](https://codecov.io/gh/saprykin/plibsys)
+[![](https://codedocs.xyz/saprykin/plibsys.svg)](https://codedocs.xyz/saprykin/plibsys/)
+[![](https://img.shields.io/badge/license-MIT-ff69b4.svg)](https://opensource.org/licenses/MIT)
+
+## About
+
+plibsys is a cross-platform system C library with some helpful routines.
+It has zero third-party dependencies and uses only native system calls.
+
+## Features
+
+plibsys gives you:
+
+* Platform independent data types
+* Threads
+* Mutexes
+* Condition variables
+* Read-write locks
+* System-wide semaphores
+* System-wide shared memory
+* Optimized spinlock
+* Atomic operations
+* Socket support (UDP, TCP, SCTP) with IPv4 and IPv6
+* Hash functions: MD5, SHA-1, SHA-2, SHA-3, GOST (R 34.11-94)
+* Binary trees: BST, red-black, AVL
+* INI file parser
+* High resolution time profiler
+* Files and directories
+* Shared library loading
+* Useful routines for linked lists, strings, hash tables
+* Macros for CPU architecture, OS and compiler detection
+* Macros for variable arguments
+
+To achieve maximum native performance on each platform several implementation models are used:
+
+* Threading models: POSIX, Solaris, OS/2, BeOS, AtheOS, AmigaOS and Win32
+* IPC models: POSIX, System V, OS/2, AmigaOS and Win32
+* Time profiler models: POSIX, Solaris, Mach, OS/2, BeOS, AmigaOS, Win32 and generic
+* Directory iterating models: POSIX, OS/2 and Win32
+* Shared library loading models: POSIX, HP-UX, OS/2, BeOS, AmigaOS and Win32
+* Atomic operations models: sync, C11, DECC, Win32 and simulated
+* Sockets: BSD with Win32 support
+
+## Platforms
+
+plibsys is a cross-platform, highly portable library, it is fully covered
+with unit tests and was tested on the following desktop platforms:
+
+* GNU/Linux
+* macOS
+* Windows
+* Cygwin, MSYS
+* FreeBSD, NetBSD, OpenBSD
+* DragonFlyBSD
+* Solaris
+* AIX
+* HP-UX
+* Tru64
+* OpenVMS
+* OS/2
+* IRIX
+* QNX Neutrino
+* UnixWare 7
+* SCO OpenServer 5
+* Haiku
+* Syllable
+* BeOS
+* AmigaOS
+
+plibsys also supports the following mobile platforms:
+
+* iOS, watchOS, tvOS
+* Android
+* BlackBerry 10
+
+It should also work on other *nix systems with or without minimal efforts.
+
+## Compilers
+
+plibsys was tested with the following compilers:
+
+* MSVC (x86, x64) 2003 and above
+* MinGW (x86, x64)
+* Open Watcom (x86)
+* Borland (x86)
+* GCC (x86, x64, PPC32be, PPC64be/le, IA-64/32, IA-64, Alpha, HPPA2.0-32, MIPS32, AArch32, SPARCv9)
+* Clang (x86, x64, PPC32be, AArch32, AArch64)
+* Intel (x86, x64)
+* QCC (x86, AArch32)
+* Oracle Solaris Studio (x86, x64, SPARCv9)
+* MIPSpro (MIPS32)
+* XL C (PPC64le)
+* DEC C (Alpha)
+* PGI (x86, x64)
+* Cray (x64)
+
+## Building
+
+Use CMake to build plibsys for target platform. For OpenVMS see platforms/vms-general directory.
+
+## Documentation
+
+Documentation for the latest stable verison is avaialble through the [GitHub Pages](http://saprykin.github.io/plibsys-docs).
+
+## License
+
+plibsys is distributed under the terms of MIT license.
+
+## More
+
+More information about the library is available on the [Wiki](https://github.com/saprykin/plibsys/wiki).
diff --git a/3rdparty/plibsys/appveyor.yml b/3rdparty/plibsys/appveyor.yml
new file mode 100644
index 0000000..8b654ca
--- /dev/null
+++ b/3rdparty/plibsys/appveyor.yml
@@ -0,0 +1,289 @@
+environment:
+ COVERITY_SCAN_PROJECT_NAME: "saprykin/plibsys"
+ COVERITY_SCAN_NOTIFICATION_EMAIL: "saprykin.spb@gmail.com"
+ COVERITY_SCAN_TOKEN:
+ secure: 6WFXzLxAMuUovtYc+u8OoruE/V6zhK2M4mZlrszRBIA=
+
+ matrix:
+ - CMAKE_GENERATOR: "Watcom WMake"
+ USE_WATCOM: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "MinGW Makefiles"
+ USE_MINGW: "1"
+ USE_MINGW_493: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "MinGW Makefiles"
+ USE_MINGW: "1"
+ USE_MINGW64: "1"
+ USE_MINGW_540: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "MinGW Makefiles"
+ USE_MINGW: "1"
+ USE_MINGW64: "1"
+ USE_MINGW_630: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "MinGW Makefiles"
+ USE_MINGW: "1"
+ USE_MINGW64: "1"
+ USE_MINGW_730: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "MinGW Makefiles"
+ USE_MINGW: "1"
+ USE_MINGW64: "1"
+ USE_MINGW_810: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Unix Makefiles"
+ USE_MSYS64: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+ - CMAKE_GENERATOR: "MSYS Makefiles"
+ USE_MSYS64: "1"
+ USE_MINGW64: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+ - CMAKE_GENERATOR: "Unix Makefiles"
+ USE_CYGWIN: "1"
+ USE_CYGWIN64: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Unix Makefiles"
+ USE_CYGWIN: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 9 2008"
+ USE_OLD_MSBUILD: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 10 2010"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 10 2010 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 11 2012"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 11 2012 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 12 2013"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 12 2013 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 14 2015"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 14 2015 Win64"
+ USE_COVERITY: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ - CMAKE_GENERATOR: "Visual Studio 15 2017"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ - CMAKE_GENERATOR: "Visual Studio 15 2017 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ - CMAKE_GENERATOR: "Visual Studio 16 2019"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+ - CMAKE_GENERATOR: "Visual Studio 16 2019"
+ CMAKE_GENERATOR_ARCH: "x64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+ - CMAKE_GENERATOR: "NMake Makefiles"
+ USE_LLVM: "1"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+
+configuration: Release
+
+version: 0.0.1.{build}
+
+branches:
+ only:
+ - master
+ - appveyor_test
+
+clone_folder: c:\projects\plibsys
+
+cache:
+ - c:\projects\i686-4.9.3-release-win32-dwarf-rt_v4-rev1.7z
+ - c:\projects\x86_64-5.4.0-release-win32-seh-rt_v5-rev0.7z
+ - c:\projects\x86_64-6.3.0-release-win32-seh-rt_v5-rev1.7z
+ - c:\projects\x86_64-7.3.0-release-win32-seh-rt_v5-rev0.7z
+ - c:\projects\x86_64-8.1.0-release-win32-seh-rt_v6-rev0.7z
+ - c:\projects\open-watcom-c-win32-1.9.exe
+ - c:\cygwin-setup-cache
+
+install:
+ - If "%USE_CYGWIN%" == "1" (
+ If "%USE_CYGWIN64%" == "1" (
+ c:\cygwin64\setup-x86_64.exe -gqnNdO -R c:\cygwin64 -s http://cygwin.mirror.constant.com -l "c:\cygwin-setup-cache" -P cmake -P cygrunsrv
+ ))
+
+ - If "%USE_CYGWIN%" == "1" (
+ If NOT "%USE_CYGWIN64%" == "1" (
+ c:\cygwin\setup-x86.exe -gqnNdO -R c:\cygwin -s http://cygwin.mirror.constant.com -l "c:\cygwin-setup-cache" -P cmake -P cygrunsrv
+ ))
+
+ - ps: >-
+ If ($env:USE_MSYS64 -eq "1") {
+ $env:PATH = "c:\msys64\usr\bin;$env:PATH";
+
+ If ($env:USE_MINGW64 -eq "1") {
+ $env:PATH = "c:\msys64\mingw64\bin;$env:PATH";
+ } Else {
+ & C:\msys64\usr\bin\mkdir -p /var/cache/pacman/pkg;
+ & pacman --sync --noconfirm cmake doxygen;
+ }
+ } ElseIf ($env:USE_MINGW -eq "1") {
+ If ($env:USE_MINGW_493 -eq "1") {
+ $MINGW_BASE = "i686-4.9.3-release-win32-dwarf-rt_v4-rev1";
+ $MINGW_VERSION = "4.9.3";
+ } ElseIf ($env:USE_MINGW_540 -eq "1") {
+ $MINGW_BASE = "x86_64-5.4.0-release-win32-seh-rt_v5-rev0";
+ $MINGW_VERSION = "5.4.0";
+ } ElseIf ($env:USE_MINGW_630 -eq "1") {
+ $MINGW_BASE = "x86_64-6.3.0-release-win32-seh-rt_v5-rev1";
+ $MINGW_VERSION = "6.3.0";
+ } ElseIf ($env:USE_MINGW_730 -eq "1") {
+ $MINGW_BASE = "x86_64-7.3.0-release-win32-seh-rt_v5-rev0";
+ $MINGW_VERSION = "7.3.0";
+ } ElseIf ($env:USE_MINGW_810 -eq "1") {
+ $MINGW_BASE = "x86_64-8.1.0-release-win32-seh-rt_v6-rev0";
+ $MINGW_VERSION = "8.1.0";
+ }
+
+ $MINGW_ARCHIVE = "$MINGW_BASE.7z";
+
+ If ($env:USE_MINGW64 -eq "1") {
+ $MINGW_URL = "https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/$MINGW_VERSION/threads-win32/seh/$MINGW_ARCHIVE/download";
+ } Else {
+ $MINGW_URL = "https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/$MINGW_VERSION/threads-win32/dwarf/$MINGW_ARCHIVE/download";
+ }
+
+ Set-Location c:\projects | Out-Null;
+
+ If (-Not (Test-Path "$MINGW_ARCHIVE")) {
+ & appveyor DownloadFile "$MINGW_URL" -FileName "$MINGW_ARCHIVE";
+ }
+
+ New-Item -ItemType directory -Path "$MINGW_BASE" | Out-Null;
+ Copy-Item "$MINGW_ARCHIVE" "$MINGW_BASE";
+
+ Set-Location "$MINGW_BASE" | Out-Null;
+ & 7z x -y "$MINGW_ARCHIVE";
+
+ If ($env:USE_MINGW64 -eq "1") {
+ $env:PATH = "c:\projects\$MINGW_BASE\mingw64\bin;C:\Program Files (x86)\CMake\bin";
+ } Else {
+ $env:PATH = "c:\projects\$MINGW_BASE\mingw32\bin;C:\Program Files (x86)\CMake\bin";
+ }
+ } ElseIf ($env:USE_WATCOM -eq "1") {
+ $WATCOM_BASE = "open-watcom-c-win32-1.9";
+ $WATCOM_INSTALLER = "$WATCOM_BASE.exe";
+ $WATCOM_URL = "https://sourceforge.net/projects/openwatcom/files/open-watcom-1.9/$WATCOM_INSTALLER/download";
+
+ Set-Location c:\projects | Out-Null;
+
+ If (-Not (Test-Path "$WATCOM_INSTALLER")) {
+ & appveyor DownloadFile "$WATCOM_URL" -FileName "$WATCOM_INSTALLER";
+ }
+
+ New-Item -ItemType directory -Path "$WATCOM_BASE" | Out-Null;
+ Copy-Item "$WATCOM_INSTALLER" "$WATCOM_BASE";
+
+ Set-Location "$WATCOM_BASE" | Out-Null;
+ & 7z x -y "$WATCOM_INSTALLER";
+
+ $CUR_LOCATION = "c:\projects\$WATCOM_BASE";
+
+ $env:PATH = "$CUR_LOCATION\binw;$env:PATH";
+ $env:PATH = "$CUR_LOCATION\binnt;$env:PATH";
+ $env:INCLUDE = "$CUR_LOCATION\h\nt;$env:INCLUDE";
+ $env:INCLUDE = "$env:INCLUDE;$CUR_LOCATION\h\nt\directx";
+ $env:INCLUDE = "$env:INCLUDE;$CUR_LOCATION\h\nt\ddk";
+ $env:INCLUDE = "$CUR_LOCATION\h;$env:INCLUDE";
+ $env:WATCOM = "$CUR_LOCATION";
+ $env:EDPATH = "$CUR_LOCATION\eddat";
+ }
+
+build_script:
+ - ps: >-
+ $BUILD_DIR = "c:\projects\plibsys-build";
+
+ New-Item -ItemType directory -Path $BUILD_DIR | Out-Null;
+ Set-Location $BUILD_DIR | Out-Null;
+
+ If ($env:USE_MSYS64 -eq "1") {
+ if ($env:USE_MINGW64 -eq "1") {
+ $BUILD_TYPE = "";
+ } Else {
+ $BUILD_TYPE = "-DCMAKE_BUILD_TYPE=$env:configuration";
+ $CTEST_PARAMS = @("-E", "pshm|psemaphore");
+ }
+
+ $BUILD_COMMAND = "make";
+ $BUILD_PARAMS = @("-j", "2");
+ } ElseIf ($env:USE_MINGW -eq "1") {
+ if ($env:USE_MINGW_493 -eq "1") {
+ $BUILD_TYPE = "-DCMAKE_BUILD_TYPE=$env:configuration";
+ } Else {
+ $BUILD_TYPE = "";
+ }
+
+ $BUILD_COMMAND = "mingw32-make";
+ $BUILD_PARAMS = @("-j", "2");
+ } ElseIf ($env:USE_CYGWIN -eq "1") {
+ If ($env:USE_CYGWIN64 -eq "1") {
+ $env:PATH = "c:\cygwin64\bin";
+ } Else {
+ $env:PATH = "c:\cygwin\bin";
+ }
+
+ $BUILD_COMMAND = "make";
+ $BUILD_PARAMS = @("-j", "2");
+
+ If ($env:APPVEYOR_REPO_BRANCH -eq "appveyor_test") {
+ & bash -lc 'cygserver-config --yes';
+ & cygrunsrv -S cygserver;
+ }
+ } ElseIf ($env:USE_LLVM -eq "1") {
+ pushd "$env:VS140COMNTOOLS\..\..\VC\bin\amd64"
+ cmd /c "vcvars64.bat&set" |
+ foreach {
+ if ($_ -match "=") {
+ $v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
+ }
+ }
+ popd
+
+ $env:PATH = "C:\Program Files\LLVM\bin;$env:PATH";
+ $BUILD_COMMAND = "nmake";
+ $BUILD_PARAMS = "/NOLOGO"
+ $BUILD_TYPE = "-DCMAKE_BUILD_TYPE=$env:configuration";
+ $CMAKE_C_COMPILER = "-DCMAKE_C_COMPILER=clang-cl.exe"
+ $CMAKE_CXX_COMPILER = "-DCMAKE_CXX_COMPILER=cl.exe"
+ } ElseIf ($env:USE_WATCOM -eq "1") {
+ $BUILD_COMMAND = "wmake";
+ } Else {
+ If ($env:USE_OLD_MSBUILD -eq "1") {
+ $env:PATH = "C:\Windows\Microsoft.NET\Framework\v3.5;$env:PATH";
+ }
+
+ $BUILD_COMMAND = "msbuild";
+ $BUILD_PARAMS = @("/verbosity:normal", "$BUILD_DIR\plibsys.sln", "/p:Configuration=$env:configuration", "/m");
+ }
+
+ $CMAKE_GENERATOR_ARGS = "-G`"$env:CMAKE_GENERATOR`"";
+
+ If (Test-Path variable:global:CMAKE_GENERATOR_ARGS) {
+ $CMAKE_GENERATOR_ARGS = "$CMAKE_GENERATOR_ARGS -A $CMAKE_GENERATOR_ARGS";
+ }
+
+ If($env:USE_COVERITY -eq "1" -And $env:APPVEYOR_REPO_BRANCH -eq "appveyor_test") {
+ & nuget install PublishCoverity -o $BUILD_DIR -excludeversion;
+
+ $COVERITY_EXE = "$BUILD_DIR\PublishCoverity\tools\PublishCoverity.exe";
+
+ # Do not build tests for Coverity
+ & cmake $CMAKE_GENERATOR_ARGS $CMAKE_C_COMPILER $CMAKE_CXX_COMPILER ../plibsys;
+
+ & cov-build --dir "$BUILD_DIR\cov-int" $BUILD_COMMAND $BUILD_PARAMS;
+
+ & $COVERITY_EXE compress -o "$BUILD_DIR\coverity.zip" -i "$BUILD_DIR\cov-int";
+ & $COVERITY_EXE publish -z "$BUILD_DIR\coverity.zip" -r $env:COVERITY_SCAN_PROJECT_NAME -t $env:COVERITY_SCAN_TOKEN -e $env:COVERITY_SCAN_NOTIFICATION_EMAIL --codeVersion $env:APPVEYOR_BUILD_VERSION;
+
+ Get-ChildItem -Path ./ -Recurse | Remove-Item -Force -Recurse;
+ }
+
+ & cmake '$CMAKE_GENERATOR_ARGS' $BUILD_TYPE $CMAKE_C_COMPILER $CMAKE_CXX_COMPILER ../plibsys;
+ & $BUILD_COMMAND $BUILD_PARAMS;
+
+ If ($env:APPVEYOR_REPO_BRANCH -eq "appveyor_test") {
+ & ctest $CTEST_PARAMS --output-on-failure -V -C Release;
+ }
diff --git a/3rdparty/plibsys/cmake/PlatformDetect.cmake b/3rdparty/plibsys/cmake/PlatformDetect.cmake
new file mode 100644
index 0000000..ab05065
--- /dev/null
+++ b/3rdparty/plibsys/cmake/PlatformDetect.cmake
@@ -0,0 +1,144 @@
+# The MIT License
+#
+# Copyright (C) 2018 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function (plibsys_detect_c_compiler result)
+ # Get target system OS
+ string (TOLOWER ${CMAKE_SYSTEM_NAME} PLIBSYS_TARGET_OS)
+
+ # Detect C compiler by it's ID
+ if (CMAKE_C_COMPILER_ID STREQUAL GNU)
+ set (PLIBSYS_C_COMPILER gcc)
+ elseif (CMAKE_C_COMPILER_ID STREQUAL MSVC)
+ set (PLIBSYS_C_COMPILER msvc)
+ else()
+ string (TOLOWER ${CMAKE_C_COMPILER_ID} PLIBSYS_C_COMPILER)
+ endif()
+
+ # Fix gcc -> qcc naming on QNX 6
+ if ((PLIBSYS_TARGET_OS STREQUAL qnx) AND (PLIBSYS_C_COMPILER STREQUAL gcc))
+ set (PLIBSYS_C_COMPILER qcc)
+ endif()
+
+ # Rename intel -> icc
+ if (PLIBSYS_C_COMPILER STREQUAL intel)
+ set (PLIBSYS_C_COMPILER icc)
+ endif()
+
+ # Rename openwatcom -> watcom
+ if (PLIBSYS_C_COMPILER STREQUAL openwatcom)
+ set (PLIBSYS_C_COMPILER watcom)
+ endif()
+
+ # Rename xl -> xlc
+ if (PLIBSYS_C_COMPILER STREQUAL xl)
+ set (PLIBSYS_C_COMPILER xlc)
+ endif()
+
+ # Assign result
+ set (${result} ${PLIBSYS_C_COMPILER} PARENT_SCOPE)
+endfunction (plibsys_detect_c_compiler)
+
+function (plibsys_detect_os_bits result)
+ if (PLIBSYS_SIZEOF_VOID_P EQUAL 8)
+ set (PLIBSYS_ARCH_BITS 64)
+ elseif (PLIBSYS_SIZEOF_VOID_P EQUAL 4)
+ set (PLIBSYS_ARCH_BITS 32)
+ elseif(PLIBSYS_SIZEOF_VOID_P EQUAL 0)
+ set (PLIBSYS_ARCH_BITS "universal")
+ else()
+ set (PLIBSYS_ARCH_BITS "unknown")
+ endif()
+
+ set (${result} ${PLIBSYS_ARCH_BITS} PARENT_SCOPE)
+endfunction (plibsys_detect_os_bits)
+
+function (plibsys_detect_cpu_arch result)
+ if (CMAKE_SYSTEM_PROCESSOR MATCHES "(i[1-9]86)|(x86_64)")
+ if (CMAKE_CROSSCOMPILING)
+ if (CMAKE_SYSTEM_PROCESSOR MATCHES "i[1-9]86")
+ set (PLIBSYS_PROCESSOR_ARCH "x86")
+ else()
+ set (PLIBSYS_PROCESSOR_ARCH "x64")
+ endif()
+ else()
+ plibsys_detect_os_bits (PLIBSYS_OS_BITS)
+ if (PLIBSYS_OS_BITS STREQUAL "32")
+ set (PLIBSYS_PROCESSOR_ARCH "x86")
+ elseif (PLIBSYS_OS_BITS STREQUAL "64")
+ set (PLIBSYS_PROCESSOR_ARCH "x64")
+ else()
+ set (PLIBSYS_PROCESSOR_ARCH "x${PLIBSYS_OS_BITS}")
+ endif()
+ endif()
+ else()
+ set (PLIBSYS_PROCESSOR_ARCH ${CMAKE_SYSTEM_PROCESSOR})
+ endif()
+
+ set (${result} ${PLIBSYS_PROCESSOR_ARCH} PARENT_SCOPE)
+endfunction (plibsys_detect_cpu_arch)
+
+function (plibsys_detect_target_os result)
+ string (TOLOWER ${CMAKE_SYSTEM_NAME} PLIBSYS_TARGET_OS)
+
+ # Rename mingw -> windows
+ if (PLIBSYS_TARGET_OS MATCHES "(mingw.*)")
+ set (PLIBSYS_TARGET_OS windows)
+ endif()
+
+ # Rename hp-ux -> hpux
+ if (PLIBSYS_TARGET_OS STREQUAL hp-ux)
+ set (PLIBSYS_TARGET_OS hpux)
+ endif()
+
+ # Rename sco_sv -> scosv
+ if (PLIBSYS_TARGET_OS STREQUAL sco_sv)
+ set (PLIBSYS_TARGET_OS scosv)
+ endif()
+
+ # Rename osf1 -> tru64
+ if (PLIBSYS_TARGET_OS STREQUAL osf1)
+ set (PLIBSYS_TARGET_OS tru64)
+ endif()
+
+ # Rename craylinuxenvironment -> linux
+ if (PLIBSYS_TARGET_OS STREQUAL craylinuxenvironment)
+ set (PLIBSYS_TARGET_OS linux)
+ endif()
+
+ set (${result} ${PLIBSYS_TARGET_OS} PARENT_SCOPE)
+endfunction (plibsys_detect_target_os)
+
+function (plibsys_detect_target_platform result)
+ plibsys_detect_target_os (PLIBSYS_TARGET_OS)
+ plibsys_detect_os_bits (PLIBSYS_OS_BITS)
+ plibsys_detect_c_compiler (PLIBSYS_C_COMPILER)
+
+ if (PLIBSYS_TARGET_OS STREQUAL windows)
+ set (PLIBSYS_TARGET_PLATFORM win${PLIBSYS_OS_BITS})
+ else()
+ set (PLIBSYS_TARGET_PLATFORM ${PLIBSYS_TARGET_OS})
+ endif()
+
+ set (PLIBSYS_TARGET_PLATFORM ${PLIBSYS_TARGET_PLATFORM}-${PLIBSYS_C_COMPILER})
+ set (${result} ${PLIBSYS_TARGET_PLATFORM} PARENT_SCOPE)
+endfunction (plibsys_detect_target_platform)
diff --git a/3rdparty/plibsys/cmake/StdargDetect.cmake b/3rdparty/plibsys/cmake/StdargDetect.cmake
new file mode 100644
index 0000000..a85f59a
--- /dev/null
+++ b/3rdparty/plibsys/cmake/StdargDetect.cmake
@@ -0,0 +1,74 @@
+# The MIT License
+#
+# Copyright (C) 2017 Jean-Damien Durand <jeandamiendurand@gmail.com>
+# Copyright (C) 2019 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function (plibsys_detect_va_copy result)
+ #
+ # On platforms that supports va_start() and al.
+ # there is sometimes the need to do va_copy() when
+ # calling another va_list aware function.
+ #
+ # This means that va_copy() is not needed (thus not available)
+ # everywhere.
+ #
+ # We depend on stdarg.h in any case, stdio.h in some cases.
+ #
+ # Known implementations vary from va_copy to __va_copy (old proposed name).
+ # We check the _va_copy eventually.
+ #
+ set (P_VA_COPY FALSE)
+ foreach (KEYWORD "va_copy" "_va_copy" "__va_copy")
+ check_c_source_compiles ("
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+
+ void f (int i, ...) {
+ va_list args1, args2;
+
+ va_start (args1, i);
+ ${KEYWORD}(args2, args1);
+ if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) {
+ exit (1);
+ }
+ va_end (args1);
+ va_end (args2);
+ }
+
+ int main () {
+ f (0, 42);
+ exit (0);
+ }"
+ PLIBSYS_${KEYWORD}
+ )
+
+ if (PLIBSYS_${KEYWORD})
+ set (P_VA_COPY ${KEYWORD})
+ break()
+ endif()
+ endforeach()
+
+ # Assign result
+ set (${result} ${P_VA_COPY} PARENT_SCOPE)
+
+endfunction (plibsys_detect_va_copy)
diff --git a/3rdparty/plibsys/cmake/ThreadNameDetect.cmake b/3rdparty/plibsys/cmake/ThreadNameDetect.cmake
new file mode 100644
index 0000000..c850d82
--- /dev/null
+++ b/3rdparty/plibsys/cmake/ThreadNameDetect.cmake
@@ -0,0 +1,135 @@
+# The MIT License
+#
+# Copyright (C) 2019 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function (plibsys_detect_thread_name has_pthread_np_h result)
+ set (PTHREAD_HEADERS "#include <pthread.h>")
+
+ if (${has_pthread_np_h})
+ set (PTHREAD_HEADERS "${PTHREAD_HEADERS}\n#include<pthread_np.h>")
+ endif()
+
+ # Check pthread_setname_np() with 1 arg
+
+ if (NOT PLIBSYS_THREAD_SETTER)
+ check_c_source_compiles ("
+ ${PTHREAD_HEADERS}
+
+ int main () {
+ pthread_setname_np (\"thread_name\");
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_SETNAME_NP_1
+ )
+
+ if (PLIBSYS_HAS_POSIX_SETNAME_NP_1)
+ set (PLIBSYS_THREAD_SETTER "pthread_setname_np")
+ endif()
+ endif()
+
+ # Check pthread_setname_np() with 2 args
+
+ if (NOT PLIBSYS_THREAD_SETTER)
+ check_c_source_compiles ("
+ ${PTHREAD_HEADERS}
+
+ int main () {
+ pthread_setname_np ((pthread_t) 0, \"thread_name\");
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_SETNAME_NP_2
+ )
+
+ if (PLIBSYS_HAS_POSIX_SETNAME_NP_2)
+ set (PLIBSYS_THREAD_SETTER "pthread_setname_np")
+ endif()
+ endif()
+
+ # Check pthread_setname_np() with 3 args
+
+ if (NOT PLIBSYS_THREAD_SETTER)
+ check_c_source_compiles ("
+ ${PTHREAD_HEADERS}
+
+ int main () {
+ pthread_setname_np ((pthread_t) 0, \"thread_name\", 0);
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_SETNAME_NP_3
+ )
+
+ if (PLIBSYS_HAS_POSIX_SETNAME_NP_3)
+ set (PLIBSYS_THREAD_SETTER "pthread_setname_np")
+ endif()
+ endif()
+
+ # Check pthread_set_name_np()
+
+ if (NOT PLIBSYS_THREAD_SETTER)
+ check_c_source_compiles ("
+ ${PTHREAD_HEADERS}
+
+ int main () {
+ pthread_set_name_np ((pthread_t) 0, \"thread_name\");
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_SET_NAME_NP
+ )
+
+ if (PLIBSYS_HAS_POSIX_SET_NAME_NP)
+ set (PLIBSYS_THREAD_SETTER "pthread_set_name_np")
+ endif()
+ endif()
+
+ # The last try is prctl()
+
+ if (NOT PLIBSYS_THREAD_SETTER)
+ check_c_source_compiles ("
+ #include <sys/prctl.h>
+ #include <linux/prctl.h>
+
+ int main () {
+ prctl (PR_SET_NAME, \"thread_name\", NULL, NULL, NULL);
+ return 0;
+ }"
+ PLIBSYS_PRCTL
+ )
+
+ if (PLIBSYS_PRCTL)
+ set (PLIBSYS_THREAD_SETTER "prctl")
+ endif()
+ endif()
+
+ # It seems that CMake (old versions like 2.8.x - 2.10.x) has a bug,
+ # such that when passing empty values to the parent scope, these variable
+ # are not treated as empty, thereby use NONE value instead
+
+ if (PLIBSYS_THREAD_SETTER STREQUAL "pthread_setname_np")
+ set (${result} "PLIBSYS_HAS_PTHREAD_SETNAME" PARENT_SCOPE)
+ elseif (PLIBSYS_THREAD_SETTER STREQUAL "pthread_set_name_np")
+ set (${result} "PLIBSYS_HAS_PTHREAD_SET_NAME" PARENT_SCOPE)
+ elseif (PLIBSYS_THREAD_SETTER STREQUAL "prctl")
+ set (${result} "PLIBSYS_HAS_PTHREAD_PRCTL" PARENT_SCOPE)
+ else()
+ set (${result} "NONE" PARENT_SCOPE)
+ endif()
+endfunction (plibsys_detect_thread_name)
diff --git a/3rdparty/plibsys/cmake/VisibilityDetect.cmake b/3rdparty/plibsys/cmake/VisibilityDetect.cmake
new file mode 100644
index 0000000..cbf23cd
--- /dev/null
+++ b/3rdparty/plibsys/cmake/VisibilityDetect.cmake
@@ -0,0 +1,127 @@
+# The MIT License
+#
+# Copyright (C) 2018 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function (plibsys_detect_visibility cflags ldflags)
+ if (WIN32 OR CYGWIN OR MSYS)
+ set (${cflags} "" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check GCC
+ check_c_source_compiles ("int main () {
+ #if (__GNUC__ >= 4) && !defined(_CRAYC) && \\\\
+ !defined(__sun) && !defined(sun) && \\\\
+ !defined(__hpux) && !defined(hpux) && \\\\
+ !defined(__sgi) && !defined(sgi) && \\\\
+ !defined(__osf__) && !defined(__osf) && \\\\
+ !defined(__OS2__) \\\\
+ !defined(_AIX) && !defined(__CYGWIN__) && !defined(__MSYS__)
+ return 0;
+ #else
+ stop_compile_here
+ #endif
+ }"
+ PLIBSYS_HAS_GCC_VISIBILITY
+ )
+
+ if (PLIBSYS_HAS_GCC_VISIBILITY)
+ set (${cflags} "-fvisibility=hidden" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check Sun Studio
+ check_c_source_compiles ("int main () {
+ #if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)) || \\\\
+ (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5110))
+ return 0;
+ #else
+ stop_compile_here
+ #endif
+ }"
+ PLIBSYS_HAS_SUN_VISIBILITY
+ )
+
+ if (PLIBSYS_HAS_SUN_VISIBILITY)
+ set (${cflags} "" PARENT_SCOPE)
+ set (${ldlags} "-xldscope=__hidden" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check IBM XL C
+ check_c_source_compiles ("int main () {
+ #if (defined(__xlC__) && (__xlC__ >= 0x0D01))
+ return 0;
+ #else
+ stop_compile_here
+ #endif
+ }"
+ PLIBSYS_HAS_XLC_VISIBILITY
+ )
+
+ if (PLIBSYS_HAS_XLC_VISIBILITY)
+ set (${cflags} "-qvisibility=hidden" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check HP C/aC++
+ check_c_source_compiles ("int main () {
+ #if (defined(__HP_cc) && (__HP_cc >= 0x061500)) || \\\\
+ (defined(__HP_aCC) && (__HP_aCC >= 0x061500))
+ return 0;
+ #else
+ stop_compile_here
+ #endif
+ }"
+ PLIBSYS_HAS_HP_VISIBILITY
+ )
+
+ if (PLIBSYS_HAS_HP_VISIBILITY)
+ set (${cflags} "-Bhidden" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check Clang
+ check_c_source_compiles ("int main () {
+ #if defined(__has_attribute) && __has_attribute(visibility)
+ return 0;
+ #else
+ stop_compile_here
+ #endif
+ }"
+ PLIBSYS_HAS_CLANG_VISIBILITY
+ )
+
+ if (PLIBSYS_HAS_CLANG_VISIBILITY)
+ set (${cflags} "-fvisibility=hidden" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+ return()
+ endif()
+
+ # Empty result
+ set (${cflags} "" PARENT_SCOPE)
+ set (${ldflags} "" PARENT_SCOPE)
+endfunction (plibsys_detect_visibility)
diff --git a/3rdparty/plibsys/codecov.yml b/3rdparty/plibsys/codecov.yml
new file mode 100644
index 0000000..fb9246c
--- /dev/null
+++ b/3rdparty/plibsys/codecov.yml
@@ -0,0 +1,7 @@
+comment:
+ layout: header, changes, diff
+coverage:
+ precision: 0
+ round: down
+ status:
+ patch: false
diff --git a/3rdparty/plibsys/platforms/aix-gcc/platform.cmake b/3rdparty/plibsys/platforms/aix-gcc/platform.cmake
new file mode 100644
index 0000000..be1d25a
--- /dev/null
+++ b/3rdparty/plibsys/platforms/aix-gcc/platform.cmake
@@ -0,0 +1,13 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LDFLAGS -L/usr/lib/threads)
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES c_r -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_THREAD_SAFE
+)
diff --git a/3rdparty/plibsys/platforms/amigaos-gcc/Platform/AmigaOS.cmake b/3rdparty/plibsys/platforms/amigaos-gcc/Platform/AmigaOS.cmake
new file mode 100644
index 0000000..2889670
--- /dev/null
+++ b/3rdparty/plibsys/platforms/amigaos-gcc/Platform/AmigaOS.cmake
@@ -0,0 +1,2 @@
+# This is a dummy file to suppress CMake warnings about unknown platform.
+# As we are doing it during cross-compilation, it is completely fine.
diff --git a/3rdparty/plibsys/platforms/amigaos-gcc/amigaos.cmake b/3rdparty/plibsys/platforms/amigaos-gcc/amigaos.cmake
new file mode 100644
index 0000000..23e88e6
--- /dev/null
+++ b/3rdparty/plibsys/platforms/amigaos-gcc/amigaos.cmake
@@ -0,0 +1,90 @@
+# In order to suppress CMake warnings about unknown platform
+get_filename_component (cur_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
+list (APPEND CMAKE_MODULE_PATH "${cur_dir}")
+
+set (CMAKE_SYSTEM_NAME AmigaOS)
+set (CMAKE_SYSTEM_VERSION 4)
+set (CMAKE_SYSTEM_PROCESSOR ppc)
+
+if (NOT AMIGA_ROOT)
+ set (AMIGA_ROOT $ENV{AMIGA_ROOT})
+
+ if (NOT AMIGA_ROOT)
+ message (FATAL_ERROR "You must define AMIGA_ROOT environment variable for toolchain")
+ endif()
+endif()
+
+set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
+set (CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+set (CMAKE_STATIC_LIBRARY_PREFIX "lib")
+set (CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+
+if (CMAKE_HOST_WIN32)
+ set (HOST_EXECUTABLE_SUFFIX ".exe")
+endif()
+
+set (CMAKE_AR
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-ar${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS ar program"
+)
+
+set (CMAKE_RANLIB
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-ranlib${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS ranlib program"
+)
+
+set (CMAKE_NM
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-nm${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS nm program"
+)
+
+set (CMAKE_OBJCOPY
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-objcopy${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS objcopy program"
+)
+
+set (CMAKE_OBJDUMP
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-objdump${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS objdump program"
+)
+
+set (CMAKE_LINKER
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-ld${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS linker program"
+)
+
+set (CMAKE_STRIP
+ "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-strip${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "AmigaOS strip program"
+)
+
+set (CMAKE_C_COMPILER "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-gcc${HOST_EXECUTABLE_SUFFIX}")
+set (CMAKE_CXX_COMPILER "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-g++${HOST_EXECUTABLE_SUFFIX}")
+set (CMAKE_ASM_COMPILER "${AMIGA_ROOT}/bin/${CMAKE_SYSTEM_PROCESSOR}-amigaos-as${HOST_EXECUTABLE_SUFFIX}")
+
+set (CMAKE_SHARED_LIBRARY_CXX_FLAGS -fPIC)
+set (CMAKE_SHARED_LIBRARY_C_FLAGS -fPIC)
+set (CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS -shared)
+set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS -shared)
+
+set (AMIGA_CLIB2_PATH "${AMIGA_ROOT}/ppc-amigaos/SDK/clib2/lib")
+
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -use-dynld -L${AMIGA_CLIB2_PATH}")
+set (CMAKE_SHARED_LINKER_FLAGS "-L${AMIGA_CLIB2_PATH}")
+
+set (CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,-rpath,")
+set (CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ":")
+set (CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG "-Wl,-rpath-link,")
+set (CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,-soname,")
+set (CMAKE_EXE_EXPORTS_CXX_FLAG "-Wl,--export-dynamic")
+
+set (CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
+set (CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+set (CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
+set (CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+set (CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
+
+set (CMAKE_FIND_ROOT_PATH ${AMIGA_ROOT})
+set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/3rdparty/plibsys/platforms/amigaos-gcc/platform.cmake b/3rdparty/plibsys/platforms/amigaos-gcc/platform.cmake
new file mode 100644
index 0000000..2e589e3
--- /dev/null
+++ b/3rdparty/plibsys/platforms/amigaos-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL amiga)
+set (PLIBSYS_IPC_MODEL amiga)
+set (PLIBSYS_TIME_PROFILER_MODEL amiga)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL amiga)
+set (PLIBSYS_RWLOCK_MODEL general)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES auto amiga unix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/android-clang/platform.cmake b/3rdparty/plibsys/platforms/android-clang/platform.cmake
new file mode 100644
index 0000000..3295b5c
--- /dev/null
+++ b/3rdparty/plibsys/platforms/android-clang/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL none)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/android-gcc/platform.cmake b/3rdparty/plibsys/platforms/android-gcc/platform.cmake
new file mode 100644
index 0000000..3295b5c
--- /dev/null
+++ b/3rdparty/plibsys/platforms/android-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL none)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/bb10-qcc/blackberry.cmake b/3rdparty/plibsys/platforms/bb10-qcc/blackberry.cmake
new file mode 100644
index 0000000..6509d24
--- /dev/null
+++ b/3rdparty/plibsys/platforms/bb10-qcc/blackberry.cmake
@@ -0,0 +1,141 @@
+set (CMAKE_SYSTEM_NAME QNX)
+set (CMAKE_SYSTEM_VERSION 8.0.0)
+set (TOOLCHAIN QNX)
+
+set (CPUVARDIR $ENV{CPUVARDIR})
+
+if (NOT CPUVARDIR)
+ message (FATAL_ERROR "CPU architecture not set")
+endif()
+
+if (${CPUVARDIR} STREQUAL "armle-v7")
+ set (CMAKE_SYSTEM_PROCESSOR armv7)
+elseif (${CPUVARDIR} STREQUAL "x86")
+ set (CMAKE_SYSTEM_PROCESSOR x86)
+else()
+ message (FATAL_ERROR "Unsupported CPU architecture: ${CPUVARDIR}")
+endif()
+
+set (QNX_HOST $ENV{QNX_HOST})
+set (QNX_TARGET $ENV{QNX_TARGET})
+
+if (NOT QNX_HOST)
+ message (FATAL_ERROR "You must define QNX_HOST environment variable for toolchain")
+endif()
+
+if (NOT QNX_TARGET)
+ message (FATAL_ERROR "You must define QNX_TARGET environment variable for toolchain")
+endif()
+
+set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
+set (CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+set (CMAKE_STATIC_LIBRARY_PREFIX "lib")
+set (CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+
+if (CMAKE_HOST_WIN32)
+ set (HOST_EXECUTABLE_SUFFIX ".exe")
+endif()
+
+set (CMAKE_MAKE_PROGRAM
+ "${QNX_HOST}/usr/bin/make${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX make program"
+)
+
+set (CMAKE_SH
+ "${QNX_HOST}/usr/bin/sh${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX shell program"
+)
+
+set (CMAKE_AR
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-ar${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX ar program"
+)
+
+set (CMAKE_RANLIB
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-ranlib${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX ranlib program"
+)
+
+set (CMAKE_NM
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-nm${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX nm program"
+)
+
+set (CMAKE_OBJCOPY
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-objcopy${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX objcopy program"
+)
+
+set (CMAKE_OBJDUMP
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-objdump${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX objdump program"
+)
+
+set (CMAKE_LINKER
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-ld${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX linker program"
+)
+
+set (CMAKE_STRIP
+ "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-strip${HOST_EXECUTABLE_SUFFIX}"
+ CACHE PATH "QNX strip program"
+)
+
+set (CMAKE_C_COMPILER "${QNX_HOST}/usr/bin/qcc${HOST_EXECUTABLE_SUFFIX}")
+set (CMAKE_CXX_COMPILER "${QNX_HOST}/usr/bin/qcc${HOST_EXECUTABLE_SUFFIX}")
+set (CMAKE_ASM_COMPILER "${QNX_HOST}/usr/bin/nto${CMAKE_SYSTEM_PROCESSOR}-as${HOST_EXECUTABLE_SUFFIX}")
+
+execute_process (COMMAND nto${CMAKE_SYSTEM_PROCESSOR}-gcc${HOST_EXECUTABLE_SUFFIX} --version
+ OUTPUT_VARIABLE QCC_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string (REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" QCC_VERSION "${QCC_VERSION}")
+
+set (CMAKE_C_COMPILER_VERSION ${QCC_VERSION})
+set (CMAKE_CXX_COMPILER_VERSION ${QCC_VERSION})
+
+set (BLACKBERRY_BASE_FLAGS "-D_REENTRANT -Wno-psabi -fstack-protector -fstack-protector-all")
+
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7")
+ set (BLACKBERRY_CPU_FLAGS "-mcpu=cortex-a9 -mthumb")
+endif()
+
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7")
+ set (BLACKBERRY_QCC_FLAGS "-Vgcc_ntoarmv7le")
+elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
+ set (BLACKBERRY_QCC_FLAGS "-Vgcc_ntox86")
+endif()
+
+set (BLACKBERRY_FLAGS "${BLACKBERRY_QCC_FLAGS} ${BLACKBERRY_BASE_FLAGS} ${BLACKBERRY_CPU_FLAGS}")
+
+set (CMAKE_C_FLAGS_DEBUG "${BLACKBERRY_FLAGS} -g" CACHE STRING "" FORCE)
+set (CMAKE_C_FLAGS_MINSIZEREL "${BLACKBERRY_FLAGS} -O2 -fstack-protector-strong -Os" CACHE STRING "" FORCE)
+set (CMAKE_C_FLAGS_RELEASE "${BLACKBERRY_FLAGS} -O2 -fstack-protector-strong -Os" CACHE STRING "" FORCE)
+set (CMAKE_C_FLAGS_RELWITHDEBINFO "${BLACKBERRY_FLAGS} -O2 -g -fstack-protector-strong" CACHE STRING "" FORCE)
+
+set (CMAKE_CXX_FLAGS_DEBUG "${BLACKBERRY_FLAGS} -lang-c++ -lstdc++ -g" CACHE STRING "" FORCE)
+set (CMAKE_CXX_FLAGS_MINSIZEREL "${BLACKBERRY_FLAGS} -lang-c++ -lstdc++ -O2 -fstack-protector-strong -Os" CACHE STRING "" FORCE)
+set (CMAKE_CXX_FLAGS_RELEASE "${BLACKBERRY_FLAGS} -lang-c++ -lstdc++ -O2 -fstack-protector-strong -Os" CACHE STRING "" FORCE)
+set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${BLACKBERRY_FLAGS} -lang-c++ -lstdc++ -O2 -g -fstack-protector-strong" CACHE STRING "" FORCE)
+
+set (CMAKE_FIND_ROOT_PATH ${QNX_TARGET})
+set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# To remove full linking paths
+link_directories (${QNX_TARGET}/${CPUVARDIR}/lib ${QNX_TARGET}/${CPUVARDIR}/usr/lib)
+
+# To distinguish from QNX
+add_definitions (-D__BLACKBERRY10__)
+
+set (CMAKE_LIBRARY_PATH
+ ${QNX_TARGET}/${CPUVARDIR}/lib
+ ${QNX_TARGET}/${CPUVARDIR}/usr/lib
+)
+
+set (CMAKE_INCLUDE_PATH
+ ${QNX_TARGET}/usr/include/c++/${QCC_VERSION}
+ ${QNX_TARGET}/usr/include/c++/${QCC_VERSION}/arm-unknown-nto-qnx8.0.0eabi
+)
diff --git a/3rdparty/plibsys/platforms/beos-gcc/platform.cmake b/3rdparty/plibsys/platforms/beos-gcc/platform.cmake
new file mode 100644
index 0000000..502313f
--- /dev/null
+++ b/3rdparty/plibsys/platforms/beos-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL beos)
+set (PLIBSYS_IPC_MODEL none)
+set (PLIBSYS_TIME_PROFILER_MODEL beos)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL beos)
+set (PLIBSYS_RWLOCK_MODEL general)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES root socket bind)
diff --git a/3rdparty/plibsys/platforms/common/HPUX.cmake b/3rdparty/plibsys/platforms/common/HPUX.cmake
new file mode 100644
index 0000000..d411066
--- /dev/null
+++ b/3rdparty/plibsys/platforms/common/HPUX.cmake
@@ -0,0 +1,15 @@
+include (CheckFunctionExists)
+
+function (plibsys_hpux_detect_libraryloader_model result)
+ message (STATUS "Checking whether dlopen() presents")
+
+ check_function_exists (dlopen PLIBSYS_HPUX_HAS_DLOPEN)
+
+ if (PLIBSYS_HPUX_HAS_DLOPEN)
+ message (STATUS "Checking whether dlopen() presents - yes")
+ set (${result} posix PARENT_SCOPE)
+ else()
+ message (STATUS "Checking whether dlopen() presents - no")
+ set (${result} shl PARENT_SCOPE)
+ endif()
+endfunction (plibsys_hpux_detect_libraryloader_model)
diff --git a/3rdparty/plibsys/platforms/common/SCOSV.cmake b/3rdparty/plibsys/platforms/common/SCOSV.cmake
new file mode 100644
index 0000000..6ef2416
--- /dev/null
+++ b/3rdparty/plibsys/platforms/common/SCOSV.cmake
@@ -0,0 +1,9 @@
+function (plibsys_scosv_print_threading_message)
+ message ("
+ You need a working port of FSU Pthreads in order to
+ compile with multi-threading support. Please refer to
+ http://moss.csc.ncsu.edu/~mueller/pthreads/ for more
+ details. Make sure that it is compiled with thread-safe
+ memory allocation (usually -DMALLOC macro definition).
+ ")
+endfunction (plibsys_scosv_print_threading_message)
diff --git a/3rdparty/plibsys/platforms/cygwin-clang/platform.cmake b/3rdparty/plibsys/platforms/cygwin-clang/platform.cmake
new file mode 100644
index 0000000..53796bd
--- /dev/null
+++ b/3rdparty/plibsys/platforms/cygwin-clang/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/cygwin-gcc/platform.cmake b/3rdparty/plibsys/platforms/cygwin-gcc/platform.cmake
new file mode 100644
index 0000000..53796bd
--- /dev/null
+++ b/3rdparty/plibsys/platforms/cygwin-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/darwin-clang/platform.cmake b/3rdparty/plibsys/platforms/darwin-clang/platform.cmake
new file mode 100644
index 0000000..38771be
--- /dev/null
+++ b/3rdparty/plibsys/platforms/darwin-clang/platform.cmake
@@ -0,0 +1,9 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL mach)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/darwin-gcc/platform.cmake b/3rdparty/plibsys/platforms/darwin-gcc/platform.cmake
new file mode 100644
index 0000000..38771be
--- /dev/null
+++ b/3rdparty/plibsys/platforms/darwin-gcc/platform.cmake
@@ -0,0 +1,9 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL mach)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/darwin-icc/platform.cmake b/3rdparty/plibsys/platforms/darwin-icc/platform.cmake
new file mode 100644
index 0000000..7b69004
--- /dev/null
+++ b/3rdparty/plibsys/platforms/darwin-icc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread imf svml irng intlc)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/darwin-pgi/platform.cmake b/3rdparty/plibsys/platforms/darwin-pgi/platform.cmake
new file mode 100644
index 0000000..791ff79
--- /dev/null
+++ b/3rdparty/plibsys/platforms/darwin-pgi/platform.cmake
@@ -0,0 +1,27 @@
+if (NOT PLIBSYS_SIZEOF_VOID_P EQUAL 4)
+ if (CMAKE_VERSION VERSION_LESS 2.8.10)
+ message (WARNING
+ "
+ Unable to detect PGI compiler version. Beware that old
+ PGI versions doesn't support shared libraries on 64-bit
+ macOS.
+ ")
+ elseif (CMAKE_C_COMPILER_VERSION VERSION_LESS 18.4)
+ message (FATAL_ERROR
+ "
+ PGI compiler before verison 18.4 doesn't support 64-bit
+ shared libraries on macOS. Use older 32-bit version of
+ the compiler instead.
+ ")
+ endif()
+endif()
+
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL mach)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/dragonfly-clang/platform.cmake b/3rdparty/plibsys/platforms/dragonfly-clang/platform.cmake
new file mode 100644
index 0000000..b801c3e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/dragonfly-clang/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/dragonfly-gcc/platform.cmake b/3rdparty/plibsys/platforms/dragonfly-gcc/platform.cmake
new file mode 100644
index 0000000..b801c3e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/dragonfly-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/freebsd-clang/platform.cmake b/3rdparty/plibsys/platforms/freebsd-clang/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/freebsd-clang/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/freebsd-gcc/platform.cmake b/3rdparty/plibsys/platforms/freebsd-gcc/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/freebsd-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/haiku-clang/platform.cmake b/3rdparty/plibsys/platforms/haiku-clang/platform.cmake
new file mode 100644
index 0000000..0c93b2d
--- /dev/null
+++ b/3rdparty/plibsys/platforms/haiku-clang/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES root network)
diff --git a/3rdparty/plibsys/platforms/haiku-gcc/platform.cmake b/3rdparty/plibsys/platforms/haiku-gcc/platform.cmake
new file mode 100644
index 0000000..0c93b2d
--- /dev/null
+++ b/3rdparty/plibsys/platforms/haiku-gcc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES root network)
diff --git a/3rdparty/plibsys/platforms/hpux-gcc/platform.cmake b/3rdparty/plibsys/platforms/hpux-gcc/platform.cmake
new file mode 100644
index 0000000..bfaa7d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/hpux-gcc/platform.cmake
@@ -0,0 +1,16 @@
+include (${PROJECT_SOURCE_DIR}/platforms/common/HPUX.cmake)
+
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL solaris)
+set (PLIBSYS_DIR_MODEL posix)
+
+plibsys_hpux_detect_libraryloader_model (PLIBSYS_LIBRARYLOADER_MODEL)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES xnet rt -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_THREAD_SAFE
+ -D_XOPEN_SOURCE_EXTENDED=1
+)
diff --git a/3rdparty/plibsys/platforms/ios-clang/ios.cmake b/3rdparty/plibsys/platforms/ios-clang/ios.cmake
new file mode 100644
index 0000000..e0df03b
--- /dev/null
+++ b/3rdparty/plibsys/platforms/ios-clang/ios.cmake
@@ -0,0 +1,419 @@
+# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software,
+# Kitware, Inc., Insight Software Consortium. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Updated by Alex Stewart (alexs.mac@gmail.com)
+#
+# *****************************************************************************
+# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com)
+# under the BSD-Clause-3 licence
+# *****************************************************************************
+#
+# INFORMATION / HELP
+#
+# The following variables control the behaviour of this toolchain:
+#
+# IOS_PLATFORM: OS (default), SIMULATOR, SIMULATOR64, TVOS or SIMULATOR_TVOS
+# OS = Build for iOS.
+# SIMULATOR = Build for x86 iPhone simulator.
+# SIMULATOR64 = Build for x64 iPhone simulator.
+# TVOS = Build for Apple tvOS.
+# SIMULATOR_TVOS = Build for x64 Apple TV Simulator.
+# WATCHOS = Build for Apple watchOS.
+# SIMULATOR_WATCHOS = Build for x86 watchOS Simulator.
+# SIMULATOR64_WATCHOS = Build for x64 watchOS Simulator.
+# IOS_DEPLOYMENT_TARGET: Minimum version for deployment target.
+# CMAKE_OSX_SYSROOT: Path to the iOS SDK to use. By default this is
+# automatically determined from IOS_PLATFORM and xcodebuild, but can also be
+# manually specified (although this should not be required).
+# CMAKE_IOS_DEVELOPER_ROOT: Path to the Developer directory for the iOS
+# platform being compiled for. By default this is automatically determined
+# from CMAKE_OSX_SYSROOT, but can also be manually specified (although this
+# should not be required).
+# ENABLE_BITCODE: (ON / OFF) Enables or disables bitcode support. Default: ON.
+# ENABLE_ARC: (ON / OFF) Enables or disables ARC support. Default: ON.
+# IOS_ARCH: (armv7 armv7s armv7k arm64 i386 x86_64) If specified, will override the
+# default architectures for the given IOS_PLATFORM. Default architectures:
+# OS = armv7 armv7s arm64
+# SIMULATOR = i386
+# SIMULATOR64 = x86_64
+# TVOS = arm64
+# SIMULATOR_TVOS = x86_64
+# WATCHOS = armv7k
+# SIMULATOR_WATCHOS = i386
+# SIMULATOR64_WATCHOS = x86_64
+#
+# Copyright 2018, Alexander Saprykin <saprykin.spb@gmail.com>
+#
+
+# Get the Xcode version being used.
+execute_process (COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERSION
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string (REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}")
+string (REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}")
+
+message (STATUS "Building with Xcode version: ${XCODE_VERSION}")
+
+# Default to building for iOS if not specified otherwise, and we cannot
+# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use
+# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly
+# determine the value of IOS_PLATFORM from the root project, as
+# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake.
+
+if (NOT DEFINED IOS_PLATFORM)
+ if (CMAKE_OSX_ARCHITECTURES)
+ if (CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*")
+ set (IOS_PLATFORM "OS")
+ elseif (CMAKE_OSX_ARCHITECTURES MATCHES "i386")
+ set (IOS_PLATFORM "SIMULATOR")
+ elseif (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
+ set (IOS_PLATFORM "SIMULATOR64")
+ endif()
+ endif()
+
+ if (NOT IOS_PLATFORM)
+ set (IOS_PLATFORM "OS")
+ endif()
+endif()
+
+set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS platform for which to build.")
+
+# Determine the platform name and architectures for use in xcodebuild commands
+# from the specified IOS_PLATFORM name.
+
+if (IOS_PLATFORM STREQUAL "OS")
+ set (XCODE_IOS_PLATFORM "iphoneos")
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "armv7;armv7s;arm64")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR")
+ set (XCODE_IOS_PLATFORM "iphonesimulator")
+ set (ENABLE_BITCODE OFF)
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "i386")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR64")
+ set (XCODE_IOS_PLATFORM "iphonesimulator")
+ set (ENABLE_BITCODE OFF)
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "x86_64")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "TVOS")
+ set (XCODE_IOS_PLATFORM "appletvos")
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "arm64")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
+ set (XCODE_IOS_PLATFORM "appletvsimulator")
+ set (ENABLE_BITCODE OFF)
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "x86_64")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "WATCHOS")
+ set (XCODE_IOS_PLATFORM "watchos")
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "armv7k")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR_WATCHOS")
+ set (XCODE_IOS_PLATFORM "watchsimulator")
+ set (ENABLE_BITCODE OFF)
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "i386")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR64_WATCHOS")
+ set (XCODE_IOS_PLATFORM "watchsimulator")
+ set (ENABLE_BITCODE OFF)
+
+ if (NOT IOS_ARCH)
+ set (IOS_ARCH "x86_64")
+ endif()
+else()
+ message (FATAL_ERROR "Invalid IOS_PLATFORM: ${IOS_PLATFORM}")
+endif()
+
+message (STATUS "Configuring iOS build for platform: ${IOS_PLATFORM}, architecture(s): ${IOS_ARCH}")
+
+# If user did not specify the SDK root to use, then query xcodebuild for it.
+
+if (NOT CMAKE_OSX_SYSROOT)
+ execute_process (COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
+ OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ message (STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
+endif()
+
+if (NOT EXISTS ${CMAKE_OSX_SYSROOT})
+ message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} does not exist.")
+endif()
+
+# Specify minimum version of deployment target.
+
+if (NOT DEFINED IOS_DEPLOYMENT_TARGET)
+ if (IOS_PLATFORM MATCHES ".*WATCHOS")
+ set (IOS_DEPLOYMENT_TARGET "2.0" CACHE STRING "Minimum watchOS version to build for." )
+ else()
+ set (IOS_DEPLOYMENT_TARGET "8.0" CACHE STRING "Minimum iOS version to build for." )
+ endif()
+
+ message (STATUS "Using the default min-version since IOS_DEPLOYMENT_TARGET not provided.")
+endif()
+
+if (NOT IOS_DEPLOYMENT_TARGET VERSION_LESS 11.0 AND NOT IOS_PLATFORM MATCHES ".*WATCHOS")
+ # iOS 11 does not support 32-bit (armv7*).
+ foreach (ARCH ${IOS_ARCH})
+ if (ARCH MATCHES "armv7.*")
+ message (STATUS "iOS architecture removed: ${ARCH} is not supported by "
+ "the minimum deployment iOS version ${IOS_DEPLOYMENT_TARGET}."
+ )
+ else()
+ list (APPEND VALID_IOS_ARCH ${ARCH})
+ endif()
+ endforeach()
+
+ set (IOS_ARCH ${VALID_IOS_ARCH})
+endif()
+
+# Use bitcode or not
+
+if (NOT DEFINED ENABLE_BITCODE)
+ # Unless specified, enable bitcode support by default
+ set (ENABLE_BITCODE ON CACHE BOOL "Wheter or not to enable bitcode")
+ message (STATUS "Enabling bitcode support by default.")
+endif()
+
+# Use ARC or not
+
+if (NOT DEFINED ENABLE_ARC)
+ # Unless specified, enable ARC support by default
+ set (ENABLE_ARC ON CACHE BOOL "Wheter or not to enable ARC")
+ message (STATUS "Enabling ARC support by default.")
+endif()
+
+# Get the SDK version information.
+
+execute_process (COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
+ OUTPUT_VARIABLE IOS_SDK_VERSION
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+# Find the Developer root for the specific iOS platform being compiled for
+# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in
+# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain
+# this information from xcrun or xcodebuild.
+
+if (NOT CMAKE_IOS_DEVELOPER_ROOT)
+ get_filename_component (IOS_PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH)
+ get_filename_component (CMAKE_IOS_DEVELOPER_ROOT ${IOS_PLATFORM_SDK_DIR} PATH)
+endif()
+
+if (NOT EXISTS ${CMAKE_IOS_DEVELOPER_ROOT})
+ message (FATAL_ERROR "Invalid CMAKE_IOS_DEVELOPER_ROOT: ${CMAKE_IOS_DEVELOPER_ROOT} does not exist.")
+endif()
+
+# Find the C & C++ compilers for the specified SDK.
+
+if (NOT CMAKE_C_COMPILER)
+ execute_process (COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang
+ OUTPUT_VARIABLE CMAKE_C_COMPILER
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message (STATUS "Using C compiler: ${CMAKE_C_COMPILER}")
+endif()
+
+if (NOT CMAKE_CXX_COMPILER)
+ execute_process (COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++
+ OUTPUT_VARIABLE CMAKE_CXX_COMPILER
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message (STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}")
+endif()
+
+# Find (Apple's) libtool.
+
+execute_process (COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool
+ OUTPUT_VARIABLE IOS_LIBTOOL
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+message (STATUS "Using libtool: ${IOS_LIBTOOL}")
+
+# Configure libtool to be used instead of ar + ranlib to build static libraries.
+# This is required on Xcode 7+, but should also work on previous versions of
+# Xcode.
+
+set (CMAKE_C_CREATE_STATIC_LIBRARY "${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS>")
+set (CMAKE_CXX_CREATE_STATIC_LIBRARY "${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS>")
+
+# Standard settings.
+
+set (CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "")
+set (CMAKE_SYSTEM_VERSION ${IOS_SDK_VERSION} CACHE INTERNAL "")
+set (UNIX TRUE CACHE BOOL "")
+set (APPLE TRUE CACHE BOOL "")
+set (IOS TRUE CACHE BOOL "")
+set (CMAKE_AR ar CACHE FILEPATH "" FORCE)
+set (CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE)
+
+# Force unset of OS X-specific deployment target (otherwise autopopulated),
+# required as of cmake 2.8.10.
+
+set (CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Must be empty for iOS builds." FORCE)
+
+# Set the architectures for which to build.
+
+set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
+
+# All iOS/Darwin specific settings - some may be redundant.
+
+set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
+set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
+set (CMAKE_SHARED_MODULE_PREFIX "lib")
+set (CMAKE_SHARED_MODULE_SUFFIX ".so")
+set (CMAKE_MODULE_EXISTS 1)
+set (CMAKE_DL_LIBS "")
+
+set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
+set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
+set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
+set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
+
+message (STATUS "Building for minimum OS version: ${IOS_DEPLOYMENT_TARGET} (SDK version: ${IOS_SDK_VERSION})")
+
+# Note that only Xcode 7+ supports the newer more specific:
+# -m${XCODE_IOS_PLATFORM}-version-min flags, older versions of Xcode use:
+# -m(ios/ios-simulator)-version-min instead.
+if (IOS_PLATFORM STREQUAL "OS")
+ if (XCODE_VERSION VERSION_LESS 7.0)
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mios-version-min=${IOS_DEPLOYMENT_TARGET}")
+ else()
+ # Xcode 7.0+ uses flags we can build directly from XCODE_IOS_PLATFORM.
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-m${XCODE_IOS_PLATFORM}-version-min=${IOS_DEPLOYMENT_TARGET}")
+ endif()
+elseif (IOS_PLATFORM STREQUAL "TVOS")
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mtvos-version-min=${IOS_DEPLOYMENT_TARGET}")
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mtvos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
+elseif (IOS_PLATFORM STREQUAL "WATCHOS")
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mwatchos-version-min=${IOS_DEPLOYMENT_TARGET}")
+elseif (IOS_PLATFORM STREQUAL "SIMULATOR_WATCHOS" OR IOS_PLATFORM STREQUAL "SIMULATOR64_WATCHOS")
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mwatchos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
+else()
+ # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min.
+ set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
+endif()
+
+message (STATUS "Version flags set to: ${XCODE_IOS_PLATFORM_VERSION_FLAGS}")
+
+if (ENABLE_BITCODE)
+ set (BITCODE "-fembed-bitcode")
+ message (STATUS "Enabling bitcode support.")
+else()
+ set (BITCODE "")
+ message (STATUS "Disabling bitcode support.")
+endif()
+
+if (ENABLE_ARC)
+ set (FOBJC_ARC "-fobjc-arc")
+ message (STATUS "Enabling ARC support.")
+else()
+ set (FOBJC_ARC "-fno-objc-arc")
+ message (STATUS "Disabling ARC support.")
+endif()
+
+set (CMAKE_C_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${C_FLAGS}")
+set (CMAKE_CXX_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CXX_FLAGS}")
+set (CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${C_LINK_FLAGS}")
+set (CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${CXX_LINK_FLAGS}")
+
+# In order to ensure that the updated compiler flags are used in try_compile()
+# tests, we have to forcibly set them in the CMake cache, not merely set them
+# in the local scope.
+
+list (APPEND VARS_TO_FORCE_IN_CACHE
+ CMAKE_C_FLAGS
+ CMAKE_CXX_FLAGS
+ CMAKE_C_LINK_FLAGS
+ CMAKE_CXX_LINK_FLAGS
+)
+
+foreach (VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE})
+ set (${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "" FORCE)
+endforeach()
+
+set (CMAKE_PLATFORM_HAS_INSTALLNAME 1)
+
+set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib")
+set (CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-dynamiclib")
+set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle")
+set (CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "-bundle")
+set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
+set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
+set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
+
+# Hack: If a new CMake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old
+# build tree (where install_name_tool was hardcoded) and where
+# CMAKE_INSTALL_NAME_TOOL isn't in the cache and still CMake didn't fail in
+# CMakeFindBinUtils.cmake (because it isn't rerun) hardcode
+# CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did
+# before, Alex.
+
+if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
+ find_program (CMAKE_INSTALL_NAME_TOOL install_name_tool)
+endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
+
+# Set the find root to the iOS developer roots and to user defined paths.
+set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT}
+ ${CMAKE_OSX_SYSROOT}
+ ${CMAKE_PREFIX_PATH}
+ CACHE string "iOS find search path root" FORCE
+)
+
+# Default to searching for frameworks first.
+
+set (CMAKE_FIND_FRAMEWORK FIRST)
+
+# Set up the default search directories for frameworks.
+
+set (CMAKE_SYSTEM_FRAMEWORK_PATH
+ ${CMAKE_OSX_SYSROOT}/System/Library/Frameworks
+ ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
+ ${CMAKE_OSX_SYSROOT}/Developer/Library/Frameworks
+)
+
+# Only search the specified iOS SDK, not the remainder of the host filesystem.
+
+set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
+set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/3rdparty/plibsys/platforms/ios-clang/platform.cmake b/3rdparty/plibsys/platforms/ios-clang/platform.cmake
new file mode 100644
index 0000000..38771be
--- /dev/null
+++ b/3rdparty/plibsys/platforms/ios-clang/platform.cmake
@@ -0,0 +1,9 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL mach)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/irix64-gcc/platform.cmake b/3rdparty/plibsys/platforms/irix64-gcc/platform.cmake
new file mode 100644
index 0000000..1a7e78e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/irix64-gcc/platform.cmake
@@ -0,0 +1,13 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_PTHREADS
+ -D_POSIX_C_SOURCE=199506L
+ -D_BSD_TYPES
+)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES pthread)
diff --git a/3rdparty/plibsys/platforms/irix64-mipspro/platform.cmake b/3rdparty/plibsys/platforms/irix64-mipspro/platform.cmake
new file mode 100644
index 0000000..1a7e78e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/irix64-mipspro/platform.cmake
@@ -0,0 +1,13 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_PTHREADS
+ -D_POSIX_C_SOURCE=199506L
+ -D_BSD_TYPES
+)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES pthread)
diff --git a/3rdparty/plibsys/platforms/linux-clang/platform.cmake b/3rdparty/plibsys/platforms/linux-clang/platform.cmake
new file mode 100644
index 0000000..f2067c4
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-clang/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/linux-cray/platform.cmake b/3rdparty/plibsys/platforms/linux-cray/platform.cmake
new file mode 100644
index 0000000..fc125c0
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-cray/platform.cmake
@@ -0,0 +1,18 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES rt dl)
+set (PLIBSYS_PLATFORM_CFLAGS "-h threadsafe -h nomessage=186 -O1")
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_GNU_SOURCE
+)
+
+message ("
+ Cray compiler has an optimization bug on SHA-1 algorithm
+ when using optimization levels higher than O1. Thus
+ O1 is enabled by default.
+ ")
diff --git a/3rdparty/plibsys/platforms/linux-gcc/platform.cmake b/3rdparty/plibsys/platforms/linux-gcc/platform.cmake
new file mode 100644
index 0000000..f2067c4
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/linux-icc/platform.cmake b/3rdparty/plibsys/platforms/linux-icc/platform.cmake
new file mode 100644
index 0000000..edf371a
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-icc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl imf svml irng intlc)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/linux-pgi/platform.cmake b/3rdparty/plibsys/platforms/linux-pgi/platform.cmake
new file mode 100644
index 0000000..defde72
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-pgi/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/linux-xlc/platform.cmake b/3rdparty/plibsys/platforms/linux-xlc/platform.cmake
new file mode 100644
index 0000000..c1b573f
--- /dev/null
+++ b/3rdparty/plibsys/platforms/linux-xlc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/msys-clang/platform.cmake b/3rdparty/plibsys/platforms/msys-clang/platform.cmake
new file mode 100644
index 0000000..53796bd
--- /dev/null
+++ b/3rdparty/plibsys/platforms/msys-clang/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/msys-gcc/platform.cmake b/3rdparty/plibsys/platforms/msys-gcc/platform.cmake
new file mode 100644
index 0000000..53796bd
--- /dev/null
+++ b/3rdparty/plibsys/platforms/msys-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_GNU_SOURCE
+)
diff --git a/3rdparty/plibsys/platforms/netbsd-clang/platform.cmake b/3rdparty/plibsys/platforms/netbsd-clang/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/netbsd-clang/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/netbsd-gcc/platform.cmake b/3rdparty/plibsys/platforms/netbsd-gcc/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/netbsd-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/openbsd-clang/platform.cmake b/3rdparty/plibsys/platforms/openbsd-clang/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/openbsd-clang/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/openbsd-gcc/platform.cmake b/3rdparty/plibsys/platforms/openbsd-gcc/platform.cmake
new file mode 100644
index 0000000..975c5df
--- /dev/null
+++ b/3rdparty/plibsys/platforms/openbsd-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/os2-gcc/platform.cmake b/3rdparty/plibsys/platforms/os2-gcc/platform.cmake
new file mode 100644
index 0000000..258bbb5
--- /dev/null
+++ b/3rdparty/plibsys/platforms/os2-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL os2)
+set (PLIBSYS_IPC_MODEL os2)
+set (PLIBSYS_TIME_PROFILER_MODEL os2)
+set (PLIBSYS_DIR_MODEL os2)
+set (PLIBSYS_RWLOCK_MODEL general)
+set (PLIBSYS_LIBRARYLOADER_MODEL os2)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES os2386)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/qnx-qcc/platform.cmake b/3rdparty/plibsys/platforms/qnx-qcc/platform.cmake
new file mode 100644
index 0000000..de75bc2
--- /dev/null
+++ b/3rdparty/plibsys/platforms/qnx-qcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_POSIX_THREAD_SAFE_FUNCTIONS
+)
diff --git a/3rdparty/plibsys/platforms/scosv-gcc/platform.cmake b/3rdparty/plibsys/platforms/scosv-gcc/platform.cmake
new file mode 100644
index 0000000..d1a2d8d
--- /dev/null
+++ b/3rdparty/plibsys/platforms/scosv-gcc/platform.cmake
@@ -0,0 +1,27 @@
+include (${PROJECT_SOURCE_DIR}/platforms/common/SCOSV.cmake)
+
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_SIMPLE_R
+)
+
+if (CMAKE_SYSTEM_VERSION VERSION_LESS "5.0")
+ set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket nsl gthreads malloc)
+
+ plibsys_scosv_print_threading_message ()
+else()
+ set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket nsl -pthread)
+ set (PLIBSYS_PLATFORM_CFLAGS -pthread)
+
+ message ("
+ SCO OpenServer 6 was not actually tested with GCC
+ compiler. This build may or may not work properly.
+ Consider running tests before usage.
+ ")
+endif()
diff --git a/3rdparty/plibsys/platforms/sunos-gcc/platform.cmake b/3rdparty/plibsys/platforms/sunos-gcc/platform.cmake
new file mode 100644
index 0000000..a980d6e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/sunos-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL solaris)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL solaris)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket nsl rt)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_POSIX_PTHREAD_SEMANTICS
+)
diff --git a/3rdparty/plibsys/platforms/sunos-sunpro/platform.cmake b/3rdparty/plibsys/platforms/sunos-sunpro/platform.cmake
new file mode 100644
index 0000000..a980d6e
--- /dev/null
+++ b/3rdparty/plibsys/platforms/sunos-sunpro/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL solaris)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL solaris)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket nsl rt)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_POSIX_PTHREAD_SEMANTICS
+)
diff --git a/3rdparty/plibsys/platforms/syllable-gcc/platform.cmake b/3rdparty/plibsys/platforms/syllable-gcc/platform.cmake
new file mode 100644
index 0000000..a61e1e0
--- /dev/null
+++ b/3rdparty/plibsys/platforms/syllable-gcc/platform.cmake
@@ -0,0 +1,12 @@
+set (PLIBSYS_THREAD_MODEL atheos)
+set (PLIBSYS_IPC_MODEL none)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_RWLOCK_MODEL general)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES rt dl)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/tru64-compaq/platform.cmake b/3rdparty/plibsys/platforms/tru64-compaq/platform.cmake
new file mode 100644
index 0000000..693ba57
--- /dev/null
+++ b/3rdparty/plibsys/platforms/tru64-compaq/platform.cmake
@@ -0,0 +1,17 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_ATOMIC_MODEL decc)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_XOPEN_SOURCE_EXTENDED=1
+ -D_POSIX_PII_SOCKET
+ -D_OSF_SOURCE
+ -D_XOPEN_SOURCE=500
+ -D_POSIX_SOURCE=199506L
+)
diff --git a/3rdparty/plibsys/platforms/tru64-gcc/platform.cmake b/3rdparty/plibsys/platforms/tru64-gcc/platform.cmake
new file mode 100644
index 0000000..ecacc1d
--- /dev/null
+++ b/3rdparty/plibsys/platforms/tru64-gcc/platform.cmake
@@ -0,0 +1,16 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL posix)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES -pthread rt)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+ -D_XOPEN_SOURCE_EXTENDED=1
+ -D_POSIX_PII_SOCKET
+ -D_OSF_SOURCE
+ -D_XOPEN_SOURCE=500
+ -D_POSIX_SOURCE=199506L
+)
diff --git a/3rdparty/plibsys/platforms/unixware-gcc/platform.cmake b/3rdparty/plibsys/platforms/unixware-gcc/platform.cmake
new file mode 100644
index 0000000..96ca256
--- /dev/null
+++ b/3rdparty/plibsys/platforms/unixware-gcc/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL posix)
+set (PLIBSYS_IPC_MODEL sysv)
+set (PLIBSYS_TIME_PROFILER_MODEL posix)
+set (PLIBSYS_DIR_MODEL posix)
+set (PLIBSYS_LIBRARYLOADER_MODEL posix)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES socket nsl -pthread)
+
+set (PLIBSYS_PLATFORM_DEFINES
+ -D_REENTRANT
+)
diff --git a/3rdparty/plibsys/platforms/vms-general/README.md b/3rdparty/plibsys/platforms/vms-general/README.md
new file mode 100644
index 0000000..9bbfc85
--- /dev/null
+++ b/3rdparty/plibsys/platforms/vms-general/README.md
@@ -0,0 +1,49 @@
+## OpenVMS
+
+This directory contains mainly a build script for OpenVMS.
+
+## Requirements
+
+* OpenVMS 8.4 or later (Alpha or IA64), VAX is not supported
+* DEC CC 6.5 or later
+* DEC CXX 7.1 or later (for tests only)
+
+## Building
+
+Library can be built with 32-bit or 64-bit pointers. By default 64-bit
+pointers are used. Use `32` parameter to switch behaviour.
+
+Test suit is optional and is not built by default. Use `TESTS` parameter to
+enable tests.
+
+There are other build parametes available, plese look inside the
+`build_vms.com` (a DCL-based script) to see the detailed description for
+all of them.
+
+Object library (.OLB) and shareable image (.EXE) are built. An object
+library acts like a widely-known static library, and a shareable image
+acts like a shared library. All libraries and tests are placed inside the
+`[.ALPHA]` or `[.IA64]` directory depending on a host architecture.
+
+Do not forget to define a logical name for a shareable image of the library
+before running programs which use it:
+
+`DEFINE PLIBSYS SYS$SYSROOT:[BUILD_DIR]PLIBSYS.EXE`
+
+You can also place an image into the `SYS$SHARE` directory instead of
+defining a logical name.
+
+Here are some examples of the build commands:
+
+* `@build_vms.com` builds only the libraries (64-bit pointers).
+* `@build_vms.com 32 TESTS` builds libraries (32-bit pointers) and all
+the tests.
+* `@build_vms.com NOLIB RUN_TESTS` only runs already built tests.
+* `@build_vms.com CLEAN` cleans all the files produced during a build.
+
+## More
+
+OpenVMS can mangle long (> 31 characters) symbol names in a compiled object
+to fit the limit. Sometimes it is useful to know the mangled name of a
+symbol. Use the `vms_shorten_symbol.c` program to get a mangled name. See
+details inside.
diff --git a/3rdparty/plibsys/platforms/vms-general/build_vms.com b/3rdparty/plibsys/platforms/vms-general/build_vms.com
new file mode 100644
index 0000000..ce5e95c
--- /dev/null
+++ b/3rdparty/plibsys/platforms/vms-general/build_vms.com
@@ -0,0 +1,616 @@
+$!
+$! Copyright 2011, Richard Levitte <richard@levitte.org>
+$! Copyright 2014, John Malmberg <wb8tyw@qsl.net>
+$! Copyright 2016-2018, Alexander Saprykin <saprykin.spb@gmail.com>
+$!
+$! Permission to use, copy, modify, and/or distribute this software for any
+$! purpose with or without fee is hereby granted, provided that the above
+$! copyright notice and this permission notice appear in all copies.
+$!
+$! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+$! WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+$! MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+$! ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+$! WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+$! ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+$! OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+$!
+$!===========================================================================
+$! Command-line options:
+$!
+$! 32 Compile with 32-bit pointers.
+$! BIGENDIAN Compile for a big endian host.
+$! CCQUAL=x Add "x" to the C compiler qualifiers.
+$! DEBUG Build in debug mode.
+$! CLEAN Only perform clean after the previous build.
+$! TESTS=(x) Build library tests. Comma separated test names or leave
+$! empty to build all the tests.
+$! Example 1 (curtain tests): TESTS=(pmem,puthread)
+$! Example 2 (all tests): TESTS
+$! RUN_TESTS Runs all tests.
+$! NOLIB Skip library buidling. Useful when you want to rebuild
+$! particular tests.
+$!===========================================================================
+$!
+$!
+$! Save the original default dev:[dir], and arrange for its restoration
+$! at exit.
+$!---------------------------------------------------------------------
+$ orig_def = f$environment("DEFAULT")
+$ on error then goto common_exit
+$ on severe_error then goto common_exit
+$ on control_y then goto common_exit
+$!
+$ ctrl_y = 1556
+$ proc = f$environment("PROCEDURE")
+$ proc_fid = f$file_attributes(proc, "FID")
+$ proc_dev = f$parse(proc, , , "DEVICE")
+$ proc_dir = f$parse(proc, , , "DIRECTORY")
+$ proc_name = f$parse(proc, , , "NAME")
+$ proc_type = f$parse(proc, , , "TYPE")
+$ proc_dev_dir = proc_dev + proc_dir
+$!
+$! Have to manually parse the device for a search list.
+$! Can not use the f$parse() as it will return the first name
+$! in the search list.
+$!
+$ orig_def_dev = f$element(0, ":", orig_def) + ":"
+$ if orig_def_dev .eqs. "::" then orig_def_dev = "sys$disk:"
+$ test_proc = orig_def_dev + proc_dir + proc_name + proc_type
+$!
+$! If we can find this file using the default directory
+$! then we know that we should use the original device from the
+$! default directory which could be a search list.
+$!
+$ test_proc_fid = f$file_attributes(test_proc, "FID")
+$!
+$ if (test_proc_fid .eq. proc_fid)
+$ then
+$ proc_dev_dir = orig_def_dev + proc_dir
+$ endif
+$!
+$! Verbose output message stuff. Define symbol to "write sys$output".
+$! vo_c - verbose output for compile
+$!
+$ vo_c := "write sys$output"
+$!
+$! Determine the main distribution directory ("[--]") in an
+$! ODS5-tolerant (case-insensitive) way. (We do assume that the only
+$! "]" or ">" is the one at the end.)
+$!
+$! Some non-US VMS installations report ">" for the directory delimiter
+$! so do not assume that it is "]".
+$!
+$ orig_def_len = f$length(orig_def)
+$ delim = f$extract(orig_def_len - 1, 1, orig_def)
+$!
+$ set default 'proc_dev_dir'
+$ set default [--.src]
+$ base_src_dir = f$environment("default")
+$ set default 'proc_dev_dir'
+$!
+$! Define the architecture-specific destination directory name
+$! -----------------------------------------------------------
+$!
+$ if (f$getsyi("HW_MODEL") .lt. 1024)
+$ then
+$ 'vo_c' "%PLIBSYS-F-NOTSUP, VAX platform is not supported, sorry :("
+$ goto common_exit
+$ else
+$ arch_name = ""
+$ arch_name = arch_name + f$edit(f$getsyi("ARCH_NAME"), "UPCASE")
+$!
+$ if (arch_name .eqs. "") then arch_name = "UNK"
+$!
+$ node_swvers = f$getsyi("node_swvers")
+$ version_patch = f$extract(1, f$length(node_swvers), node_swvers)
+$ maj_ver = f$element(0, ".", version_patch)
+$ min_ver_patch = f$element(1, ".", version_patch)
+$ min_ver = f$element(0, "-", min_ver_patch)
+$ patch = f$element(1, "-", min_ver_patch)
+$!
+$ if maj_ver .lts. "8" .or. min_ver .lts. "4"
+$ then
+$ 'vo_c' "%PLIBSYS-F-NOTSUP, only OpenVMS 8.4 and above are supported, sorry :("
+$ goto common_exit
+$ endif
+$ endif
+$!
+$ objdir = proc_dev_dir - delim + ".''arch_name'" + delim
+$!
+$! Parse input arguments
+$! ---------------------
+$! Allow arguments to be grouped together with comma or separated by spaces
+$! Do no know if we will need more than 8.
+$ args = "," + p1 + "," + p2 + "," + p3 + "," + p4 + ","
+$ args = args + p5 + "," + p6 + "," + p7 + "," + p8 + ","
+$!
+$! Provide lower case version to simplify parsing.
+$ args_lower = f$edit(args, "LOWERCASE,COLLAPSE")
+$!
+$ args_len = f$length(args)
+$ args_lower_len = f$length(args_lower)
+$!
+$ if f$locate(",clean,", args_lower) .lt. args_lower_len
+$ then
+$ 'vo_c' "Cleaning up previous build..."
+$ set default 'proc_dev_dir'
+$!
+$ if f$search("''arch_name'.DIR") .nes. ""
+$ then
+$ set prot=w:d []'arch_name'.DIR;*
+$ delete/tree [.'arch_name'...]*.*;*
+$ delete []'arch_name'.DIR;*
+$ endif
+$!
+$ goto common_exit
+$ endif
+$!
+$ build_64 = 1
+$ if f$locate(",32,", args_lower) .lt. args_lower_len
+$ then
+$ build_64 = 0
+$ endif
+$!
+$ big_endian = 0
+$ if f$locate(",bigendian,", args_lower) .lt. args_lower_len
+$ then
+$ big_endian = 1
+$ endif
+$!
+$ cc_extra = ""
+$ args_loc = f$locate(",ccqual=", args_lower)
+$ if args_loc .lt. args_lower_len
+$ then
+$ arg = f$extract(args_loc + 1, args_lower_len, args_lower)
+$ arg_val = f$element(0, ",", arg)
+$ cc_extra = f$element(1, "=", arg_val)
+$ endif
+$!
+$ is_debug = 0
+$ if f$locate(",debug,", args_lower) .lt. args_lower_len
+$ then
+$ is_debug = 1
+$ endif
+$!
+$ is_tests = 0
+$ test_list = ""
+$ if f$locate(",tests,", args_lower) .lt. args_lower_len
+$ then
+$ is_tests = 1
+$ else
+$ args_loc = f$locate(",tests=(", args_lower)
+$ if args_loc .lt. args_lower_len
+$ then
+$ is_tests = 1
+$ arg = f$extract(args_loc + 1, args_lower_len, args_lower)
+$ arg_val = f$element(0, ")", arg)
+$ test_list_val = f$element(1, "=", arg_val) - "(" - ")"
+$ test_list_val = f$edit(test_list_val, "COLLAPSE")
+$ test_list_counter = 0
+$
+$ test_list_loop:
+$ next_test_val = f$element (test_list_counter, ",", test_list_val)
+$ if next_test_val .nes. "" .and. next_test_val .nes. ","
+$ then
+$ test_list = test_list + next_test_val + " "
+$ test_list_counter = test_list_counter + 1
+$ goto test_list_loop
+$ endif
+$ endif
+$ endif
+$!
+$ run_tests = 0
+$ if f$locate(",run_tests,", args_lower) .lt. args_lower_len
+$ then
+$ run_tests = 1
+$ endif
+$!
+$! Prepare build directory
+$! -----------------------
+$!
+$! When building on a search list, need to do a create to make sure that
+$! the output directory exists, since the clean procedure tries to delete
+$! it.
+$!
+$ if f$search("''proc_dev_dir'''arch_name'.DIR") .eqs. ""
+$ then
+$ create/dir 'objdir'/prot=o:rwed
+$ endif
+$!
+$ set default 'objdir'
+$ if f$search("CXX_REPOSITORY.DIR") .nes. ""
+$ then
+$ set prot=w:d []CXX_REPOSITORY.DIR;*
+$ delete/tree [.CXX_REPOSITORY...]*.*;*
+$ delete []CXX_REPOSITORY.DIR;*
+$ endif
+$!
+$ if f$locate(",nolib,", args_lower) .lt. args_lower_len
+$ then
+$ goto build_tests
+$ endif
+$!
+$! Generate platform-specific config file
+$! --------------------------------------
+$!
+$ if f$search("plibsysconfig.h") .nes. "" then delete plibsysconfig.h;*
+$!
+$! Get the version number
+$! ----------------------
+$!
+$ i = 0
+$ open/read/error=version_loop_end vhf [---]CMakeLists.txt
+$ version_loop:
+$ read/end=version_loop_end vhf line_in
+$!
+$ if line_in .eqs. "" then goto version_loop
+$!
+$ if f$locate("set (PLIBSYS_VERSION_MAJOR ", line_in) .eq. 0
+$ then
+$ plibsys_vmajor = f$element(2, " ", line_in) - ")"
+$ i = i + 1
+$ endif
+$!
+$ if f$locate("set (PLIBSYS_VERSION_MINOR ", line_in) .eq. 0
+$ then
+$ plibsys_vminor = f$element(2, " ", line_in) - ")"
+$ i = i + 1
+$ endif
+$!
+$ if f$locate("set (PLIBSYS_VERSION_PATCH ", line_in) .eq. 0
+$ then
+$ plibsys_vpatch = f$element(2, " ", line_in) - ")"
+$ i = i + 1
+$ endif
+$!
+$ if f$locate("set (PLIBSYS_VERSION_NUM ", line_in) .eq. 0
+$ then
+$ plibsys_vnum = f$element(2, " ", line_in) - ")"
+$ i = i + 1
+$ endif
+$!
+$ if i .lt 4 then goto version_loop
+$ version_loop_end:
+$ close vhf
+$!
+$! Write config file
+$! -----------------
+$!
+$ open/write/error=config_write_end chf plibsysconfig.h
+$ write chf "#ifndef PLIBSYS_HEADER_PLIBSYSCONFIG_H"
+$ write chf "#define PLIBSYS_HEADER_PLIBSYSCONFIG_H"
+$ write chf ""
+$ write chf "#define PLIBSYS_VERSION_MAJOR ''plibsys_vmajor'"
+$ write chf "#define PLIBSYS_VERSION_MINOR ''plibsys_vminor'"
+$ write chf "#define PLIBSYS_VERSION_PATCH ''plibsys_vpatch'"
+$ write chf "#define PLIBSYS_VERSION_STR ""''plibsys_vmajor'.''plibsys_vminor'.''plibsys_vpatch'"""
+$ write chf "#define PLIBSYS_VERSION ''plibsys_vnum'"
+$ write chf ""
+$ write chf "#define PLIBSYS_SIZEOF_SAFAMILY_T 1"
+$ write chf ""
+$ write chf "#include <pmacros.h>"
+$ write chf ""
+$ write chf "#include <float.h>"
+$ write chf "#include <limits.h>"
+$ write chf ""
+$ write chf "P_BEGIN_DECLS"
+$ write chf ""
+$ write chf "#define P_MINFLOAT FLT_MIN"
+$ write chf "#define P_MAXFLOAT FLT_MAX"
+$ write chf "#define P_MINDOUBLE DBL_MIN"
+$ write chf "#define P_MAXDOUBLE DBL_MAX"
+$ write chf "#define P_MINSHORT SHRT_MIN"
+$ write chf "#define P_MAXSHORT SHRT_MAX"
+$ write chf "#define P_MAXUSHORT USHRT_MAX"
+$ write chf "#define P_MININT INT_MIN"
+$ write chf "#define P_MAXINT INT_MAX"
+$ write chf "#define P_MAXUINT UINT_MAX"
+$ write chf "#define P_MINLONG LONG_MIN"
+$ write chf "#define P_MAXLONG LONG_MAX"
+$ write chf "#define P_MAXULONG ULONG_MAX"
+$ write chf ""
+$ write chf "#define PLIBSYS_MMAP_HAS_MAP_ANONYMOUS"
+$ write chf "#define PLIBSYS_HAS_NANOSLEEP"
+$ write chf "#define PLIBSYS_HAS_GETADDRINFO"
+$ write chf "#define PLIBSYS_HAS_POSIX_SCHEDULING"
+$ write chf "#define PLIBSYS_HAS_POSIX_STACKSIZE"
+$ write chf "#define PLIBSYS_HAS_SOCKADDR_STORAGE"
+$ write chf "#define PLIBSYS_SOCKADDR_HAS_SA_LEN"
+$ write chf "#define PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID"
+$ write chf "#define PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO"
+$ write chf ""
+$!
+$ if build_64 .eqs. "1"
+$ then
+$ write chf "#define PLIBSYS_SIZEOF_VOID_P 8"
+$ write chf "#define PLIBSYS_SIZEOF_SIZE_T 8"
+$ else
+$ write chf "#define PLIBSYS_SIZEOF_VOID_P 4"
+$ write chf "#define PLIBSYS_SIZEOF_SIZE_T 4"
+$ endif
+$!
+$ write chf "#define PLIBSYS_SIZEOF_LONG 4"
+$ write chf ""
+$!
+$ if big_endian .eqs. "1"
+$ then
+$ write chf "#define P_BYTE_ORDER P_BIG_ENDIAN"
+$ else
+$ write chf "#define P_BYTE_ORDER P_LITTLE_ENDIAN"
+$ endif
+$!
+$ write chf ""
+$ write chf "P_END_DECLS"
+$ write chf ""
+$ write chf "#endif /* PLIBSYS_HEADER_PLIBSYSCONFIG_H */"
+$ config_write_end:
+$ close chf
+$!
+$! Prepare sources for compilation
+$! -------------------------------
+$!
+$ cc_link_params = ""
+$ cc_params = "/NAMES=(AS_IS,SHORTENED)"
+$ cc_params = cc_params + "/DEFINE=(PLIBSYS_COMPILATION,_REENTRANT,_POSIX_EXIT)"
+$ cc_params = cc_params + "/INCLUDE_DIRECTORY=(''objdir',''base_src_dir')"
+$ cc_params = cc_params + "/FLOAT=IEEE/IEEE_MODE=DENORM_RESULTS"
+$!
+$ if build_64 .eqs. "1"
+$ then
+$ cc_params = cc_params + "/POINTER_SIZE=64"
+$ else
+$ cc_params = cc_params + "/POINTER_SIZE=32"
+$ endif
+$!
+$ if cc_extra .nes. ""
+$ then
+$ cc_params = cc_params + " " + cc_extra
+$ endif
+$!
+$ if is_debug .eqs. "1"
+$ then
+$ cc_params = cc_params + "/DEBUG/NOOPTIMIZE/LIST/SHOW=ALL"
+$ cc_link_params = "/DEBUG/TRACEBACK"
+$ else
+$ cc_link_params = "/NODEBUG/NOTRACEBACK"
+$ endif
+$!
+$ plibsys_src = "patomic-decc.c pcondvariable-posix.c pcryptohash-gost3411.c pcryptohash-md5.c"
+$ plibsys_src = plibsys_src + " pcryptohash-sha1.c pcryptohash-sha2-256.c pcryptohash-sha2-512.c"
+$ plibsys_src = plibsys_src + " pcryptohash-sha3.c pcryptohash.c pdir-posix.c pdir.c"
+$ plibsys_src = plibsys_src + " perror.c pfile.c phashtable.c pinifile.c pipc.c plibraryloader-posix.c"
+$ plibsys_src = plibsys_src + " plist.c pmain.c pmem.c pmutex-posix.c pprocess.c prwlock-posix.c"
+$ plibsys_src = plibsys_src + " psemaphore-posix.c pshm-posix.c pshmbuffer.c psocket.c"
+$ plibsys_src = plibsys_src + " psocketaddress.c pspinlock-decc.c pstring.c psysclose-unix.c"
+$ plibsys_src = plibsys_src + " ptimeprofiler-posix.c ptimeprofiler.c ptree-avl.c ptree-bst.c"
+$ plibsys_src = plibsys_src + " ptree-rb.c ptree.c puthread-posix.c puthread.c"
+$!
+$! Inform about building
+$! ---------------------
+$!
+$ if build_64 .eqs. "1"
+$ then
+$ 'vo_c' "Building for ''arch_name' (64-bit)"
+$ else
+$ 'vo_c' "Building for ''arch_name' (32-bit)"
+$ endif
+$!
+$! Compile library modules
+$! -----------------------
+$!
+$ 'vo_c' "Compiling object modules..."
+$ src_counter = 0
+$ plibsys_src = f$edit(plibsys_src, "COMPRESS")
+$ plibsys_objs = ""
+$!
+$ src_loop:
+$ next_src = f$element (src_counter, " ", plibsys_src)
+$ if next_src .nes. "" .and. next_src .nes. " "
+$ then
+$ 'vo_c' "[CC] ''next_src'"
+$ cc [---.src]'next_src' 'cc_params'
+$!
+$ src_counter = src_counter + 1
+$!
+$ obj_file = f$extract (0, f$length (next_src) - 1, next_src) + "obj"
+$ plibsys_objs = plibsys_objs + "''obj_file',"
+$ purge 'obj_file'
+$!
+$ goto src_loop
+$ endif
+$!
+$ plibsys_objs = f$extract (0, f$length (plibsys_objs) - 1, plibsys_objs)
+$!
+$! Create library
+$! --------------
+$!
+$ 'vo_c' "Creating object library..."
+$ library/CREATE/INSERT/REPLACE /LIST=PLIBSYS.LIS PLIBSYS.OLB 'plibsys_objs'
+$ library/COMPRESS PLIBSYS.OLB
+$ purge PLIBSYS.OLB
+$ purge PLIBSYS.LIS
+$!
+$ 'vo_c' "Creating shared library..."
+$ link/SHAREABLE=PLIBSYS.EXE /MAP=PLIBSYS.MAP 'cc_link_params' 'plibsys_objs', [-]plibsys.opt/OPTION
+$ purge PLIBSYS.EXE
+$ purge PLIBSYS.MAP
+$!
+$! Testing area
+$! ------------
+$!
+$ build_tests:
+$ test_list_full = "patomic pcondvariable pcryptohash pdir"
+$ test_list_full = test_list_full + " perror pfile phashtable pinifile plibraryloader plist"
+$ test_list_full = test_list_full + " pmacros pmain pmem pmutex pprocess prwlock psemaphore"
+$ test_list_full = test_list_full + " pshm pshmbuffer psocket psocketaddress pspinlock pstdarg"
+$ test_list_full = test_list_full + " pstring ptimeprofiler ptree ptypes puthread"
+$!
+$ if is_tests .eqs. "0"
+$ then
+$ goto build_done
+$ endif
+$!
+$! Write link options file
+$! -----------------------
+$!
+$ if f$search("plibsys_link.opt") .nes. "" then delete plibsys_link.opt;*
+$!
+$ open/write/error=link_write_end lhf plibsys_link.opt
+$ write lhf "''objdir'PLIBSYS.EXE/SHARE"
+$ write lhf ""
+$ link_write_end:
+$ close lhf
+$!
+$! Compile tests
+$! -------------------------
+$!
+$ if test_list .nes. ""
+$ then
+$ plibsys_tests = f$edit(test_list, "TRIM")
+$ else
+$ plibsys_tests = test_list_full
+$ endif
+$!
+$ 'vo_c' "Compiling test executables..."
+$ test_counter = 0
+$ plibsys_tests = f$edit(plibsys_tests, "COMPRESS")
+$!
+$ cxx_params = "/INCLUDE=(''objdir',''base_src_dir')"
+$ cxx_params = cxx_params + "/DEFINE=(__USE_STD_IOSTREAM)/NAMES=(AS_IS, SHORTENED)"
+$ cxx_params = cxx_params + "/FLOAT=IEEE/IEEE_MODE=DENORM_RESULTS"
+$!
+$ if build_64 .eqs. "1"
+$ then
+$ set noon
+$ define/user/nolog sys$output NL:
+$ define/user/nolog sys$error NL:
+$ cxx/POINTER_SIZE=64=ARGV NL:
+$!
+$ if ($STATUS .and. %X0FFF0000) .eq. %X00030000
+$ then
+$!
+$! If we got here, it means DCL complained like this:
+$! %DCL-W-NOVALU, value not allowed - remove value specification
+$! \64=\
+$!
+$! If the compiler was run, logicals defined in /USER would
+$! have been deassigned automatically. However, when DCL
+$! complains, they aren't, so we do it here (it might be
+$! unnecessary, but just in case there will be another error
+$! message further on that we don't want to miss).
+$!
+$ deassign/user/nolog sys$error
+$ deassign/user/nolog sys$output
+$ cxx_params = cxx_params + "/POINTER_SIZE=64"
+$ else
+$ cxx_params = cxx_params + "/POINTER_SIZE=64=ARGV"
+$ endif
+$ else
+$ cxx_params = cxx_params + "/POINTER_SIZE=32"
+$ endif
+$!
+$ if is_debug .eqs. "1"
+$ then
+$ cxx_params = cxx_params + "/DEBUG/NOOPTIMIZE/LIST/SHOW=ALL"
+$ endif
+$!
+$ test_loop:
+$ next_test = f$element (test_counter, " ", plibsys_tests)
+$ if next_test .nes. "" .and. next_test .nes. " "
+$ then
+$ next_test = next_test + "_test"
+$ 'vo_c' "[CXX ] ''next_test'.cpp"
+$ cxx [---.tests]'next_test'.cpp 'cxx_params'
+$!
+$ 'vo_c' "[CXXLINK] ''next_test'.obj"
+$ cxxlink 'next_test'.obj,'objdir'plibsys_link.opt/OPTION /THREADS_ENABLE
+$!
+$ if f$search("CXX_REPOSITORY.DIR") .nes. ""
+$ then
+$ set prot=w:d []CXX_REPOSITORY.DIR;*
+$ delete/tree [.CXX_REPOSITORY...]*.*;*
+$ delete []CXX_REPOSITORY.DIR;*
+$ endif
+$!
+$ purge 'next_test'.obj
+$ purge 'next_test'.exe
+$!
+$ test_counter = test_counter + 1
+$ goto test_loop
+$ endif
+$!
+$ build_done:
+$ 'vo_c' "Build done."
+$!
+$! Run unit tests
+$! --------------
+$!
+$ if run_tests .eqs. "0"
+$ then
+$ if is_tests .eqs. "1"
+$ then
+$ 'vo_c' "To run tests invoke: @build_vms.com NOLIB RUN_TESTS"
+$ endif
+$ goto common_exit
+$ endif
+$!
+$ 'vo_c' "Running tests..."
+$ test_counter = 0
+$ tests_passed = 0
+$!
+$ run_loop:
+$ next_test = f$element (test_counter, " ", test_list_full)
+$ if next_test .nes. "" .and. next_test .nes. " "
+$ then
+$ if f$search("''next_test'_test.exe") .eqs. ""
+$ then
+$ 'vo_c' "[SKIP] Test not found: ''next_test'"
+$ goto run_loop_next
+$ endif
+$!
+$ 'vo_c' "[RUN ] ''next_test'"
+$!
+$ define/user/nolog sys$error NL:
+$ define/user/nolog sys$output NL:
+$ define/user/nolog plibsys 'objdir'PLIBSYS.EXE
+$ define/user/nolog test_imgdir 'objdir'
+$!
+$! Disable error cheking for the test binary
+$!
+$ set noon
+$!
+$ xrun := $test_imgdir:'next_test'_test.exe
+$ if next_test .eqs. "plibraryloader"
+$ then
+$ xrun 'objdir'PLIBSYS.EXE
+$ else
+$ xrun
+$ endif
+$!
+$ if $STATUS .eqs. "%X00000001"
+$ then
+$ 'vo_c' "[PASS] Test passed: ''next_test'"
+$ tests_passed = tests_passed + 1
+$ else
+$ 'vo_c' "[FAIL] *** Test failed: ''next_test'"
+$ endif
+$!
+$ set on
+$!
+$ run_loop_next:
+$ test_counter = test_counter + 1
+$ goto run_loop
+$ endif
+$!
+$ 'vo_c' "Tests passed: ''tests_passed'/''test_counter'"
+$!
+$! In case of error during the last test
+$ deassign/user/nolog sys$error
+$ deassign/user/nolog sys$output
+$ deassign/user/nolog plibsys
+$ deassign/user/nolog test_imgdir
+$!
+$ common_exit:
+$ set default 'orig_def'
+$ exit
diff --git a/3rdparty/plibsys/platforms/vms-general/plibsys.opt b/3rdparty/plibsys/platforms/vms-general/plibsys.opt
new file mode 100644
index 0000000..408b884
--- /dev/null
+++ b/3rdparty/plibsys/platforms/vms-general/plibsys.opt
@@ -0,0 +1,540 @@
+GSMATCH=LEQUAL,3,0
+IDENTIFICATION="plibsys"
+CASE_SENSITIVE=YES
+!
+! patomic.h
+!
+SYMBOL_VECTOR=(p_atomic_int_get=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_GET/p_atomic_int_get=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_set=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_SET/p_atomic_int_set=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_inc=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_INC/p_atomic_int_inc=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_dec_and_test=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_DEC_AND_TEST/p_atomic_int_dec_and_test=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_compare_an2fhrots$=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_COMPARE_AN2UA3PBG$/p_atomic_int_compare_an2fhrots$=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_add=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_ADD/p_atomic_int_add=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_and=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_AND/p_atomic_int_and=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_or=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_OR/p_atomic_int_or=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_int_xor=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_INT_XOR/p_atomic_int_xor=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_get=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_GET/p_atomic_pointer_get=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_set=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_SET/p_atomic_pointer_set=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_compar0usq95l$=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_COMPAR19ERBSM$/p_atomic_pointer_compar0usq95l$=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_add=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_ADD/p_atomic_pointer_add=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_and=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_AND/p_atomic_pointer_and=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_or=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_OR/p_atomic_pointer_or=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_pointer_xor=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_POINTER_XOR/p_atomic_pointer_xor=PROCEDURE)
+SYMBOL_VECTOR=(p_atomic_is_lock_free=PROCEDURE)
+SYMBOL_VECTOR=(P_ATOMIC_IS_LOCK_FREE/p_atomic_is_lock_free=PROCEDURE)
+!
+! pcondvariable.h
+!
+SYMBOL_VECTOR=(p_cond_variable_new=PROCEDURE)
+SYMBOL_VECTOR=(P_COND_VARIABLE_NEW/p_cond_variable_new=PROCEDURE)
+SYMBOL_VECTOR=(p_cond_variable_free=PROCEDURE)
+SYMBOL_VECTOR=(P_COND_VARIABLE_FREE/p_cond_variable_free=PROCEDURE)
+SYMBOL_VECTOR=(p_cond_variable_wait=PROCEDURE)
+SYMBOL_VECTOR=(P_COND_VARIABLE_WAIT/p_cond_variable_wait=PROCEDURE)
+SYMBOL_VECTOR=(p_cond_variable_signal=PROCEDURE)
+SYMBOL_VECTOR=(P_COND_VARIABLE_SIGNAL/p_cond_variable_signal=PROCEDURE)
+SYMBOL_VECTOR=(p_cond_variable_broadcast=PROCEDURE)
+SYMBOL_VECTOR=(P_COND_VARIABLE_BROADCAST/p_cond_variable_broadcast=PROCEDURE)
+!
+! pcryptohash.h
+!
+SYMBOL_VECTOR=(p_crypto_hash_new=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_NEW/p_crypto_hash_new=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_update=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_UPDATE/p_crypto_hash_update=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_reset=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_RESET/p_crypto_hash_reset=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_get_string=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_GET_STRING/p_crypto_hash_get_string=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_get_digest=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_GET_DIGEST/p_crypto_hash_get_digest=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_get_length=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_GET_LENGTH/p_crypto_hash_get_length=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_get_type=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_GET_TYPE/p_crypto_hash_get_type=PROCEDURE)
+SYMBOL_VECTOR=(p_crypto_hash_free=PROCEDURE)
+SYMBOL_VECTOR=(P_CRYPTO_HASH_FREE/p_crypto_hash_free=PROCEDURE)
+!
+! pdir.h
+!
+SYMBOL_VECTOR=(p_dir_new=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_NEW/p_dir_new=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_create=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_CREATE/p_dir_create=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_remove=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_REMOVE/p_dir_remove=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_is_exists=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_IS_EXISTS/p_dir_is_exists=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_get_path=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_GET_PATH/p_dir_get_path=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_get_next_entry=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_GET_NEXT_ENTRY/p_dir_get_next_entry=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_rewind=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_REWIND/p_dir_rewind=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_entry_free=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_ENTRY_FREE/p_dir_entry_free=PROCEDURE)
+SYMBOL_VECTOR=(p_dir_free=PROCEDURE)
+SYMBOL_VECTOR=(P_DIR_FREE/p_dir_free=PROCEDURE)
+!
+! perror.h
+!
+SYMBOL_VECTOR=(p_error_new=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_NEW/p_error_new=PROCEDURE)
+SYMBOL_VECTOR=(p_error_new_literal=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_NEW_LITERAL/p_error_new_literal=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_message=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_MESSAGE/p_error_get_message=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_code=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_CODE/p_error_get_code=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_native_code=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_NATIVE_CODE/p_error_get_native_code=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_domain=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_DOMAIN/p_error_get_domain=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_last_system=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_LAST_SYSTEM/p_error_get_last_system=PROCEDURE)
+SYMBOL_VECTOR=(p_error_get_last_net=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_GET_LAST_NET/p_error_get_last_net=PROCEDURE)
+SYMBOL_VECTOR=(p_error_copy=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_COPY/p_error_copy=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_error=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_ERROR/p_error_set_error=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_error_p=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_ERROR_P/p_error_set_error_p=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_code=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_CODE/p_error_set_code=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_native_code=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_NATIVE_CODE/p_error_set_native_code=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_message=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_MESSAGE/p_error_set_message=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_last_system=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_LAST_SYSTEM/p_error_set_last_system=PROCEDURE)
+SYMBOL_VECTOR=(p_error_set_last_net=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_SET_LAST_NET/p_error_set_last_net=PROCEDURE)
+SYMBOL_VECTOR=(p_error_clear=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_CLEAR/p_error_clear=PROCEDURE)
+SYMBOL_VECTOR=(p_error_free=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_FREE/p_error_free=PROCEDURE)
+!
+! pfile.h
+!
+SYMBOL_VECTOR=(p_file_is_exists=PROCEDURE)
+SYMBOL_VECTOR=(P_ERROR_IS_EXISTS/p_file_is_exists=PROCEDURE)
+SYMBOL_VECTOR=(p_file_remove=PROCEDURE)
+SYMBOL_VECTOR=(P_FILE_REMOVE/p_file_remove=PROCEDURE)
+!
+! phashtable.h
+!
+SYMBOL_VECTOR=(p_hash_table_new=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_NEW/p_hash_table_new=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_insert=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_INSERT/p_hash_table_insert=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_lookup=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_LOOKUP/p_hash_table_lookup=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_keys=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_KEYS/p_hash_table_keys=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_values=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_VALUES/p_hash_table_values=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_free=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_FREE/p_hash_table_free=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_remove=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_REMOVE/p_hash_table_remove=PROCEDURE)
+SYMBOL_VECTOR=(p_hash_table_lookup_by_value=PROCEDURE)
+SYMBOL_VECTOR=(P_HASH_TABLE_LOOKUP_BY_VALUE/p_hash_table_lookup_by_value=PROCEDURE)
+!
+! pinifile.h
+!
+SYMBOL_VECTOR=(p_ini_file_new=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_NEW/p_ini_file_new=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_free=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_FREE/p_ini_file_free=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parse=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARSE/p_ini_file_parse=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_is_parsed=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_IS_PARSED/p_ini_file_is_parsed=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_sections=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_SECTIONS/p_ini_file_sections=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_keys=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_KEYS/p_ini_file_keys=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_is_key_exists=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_IS_KEY_EXISTS/p_ini_file_is_key_exists=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parameter_string=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARAMETER_STRING/p_ini_file_parameter_string=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parameter_int=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARAMETER_INT/p_ini_file_parameter_int=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parameter_double=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARAMETER_DOUBLE/p_ini_file_parameter_double=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parameter_boolean=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARAMETER_BOOLEAN/p_ini_file_parameter_boolean=PROCEDURE)
+SYMBOL_VECTOR=(p_ini_file_parameter_list=PROCEDURE)
+SYMBOL_VECTOR=(P_INI_FILE_PARAMETER_LIST/p_ini_file_parameter_list=PROCEDURE)
+!
+! plibraryloader.h
+!
+SYMBOL_VECTOR=(p_library_loader_new=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBRARY_LOADER_NEW/p_library_loader_new=PROCEDURE)
+SYMBOL_VECTOR=(p_library_loader_get_symbol=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBRARY_LOADER_GET_SYMBOL/p_library_loader_get_symbol=PROCEDURE)
+SYMBOL_VECTOR=(p_library_loader_free=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBRARY_LOADER_FREE/p_library_loader_free=PROCEDURE)
+SYMBOL_VECTOR=(p_library_loader_get_last_error=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBRARY_LOADER_GET_LAST_ERROR/p_library_loader_get_last_error=PROCEDURE)
+SYMBOL_VECTOR=(p_library_loader_is_ref_counted=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBRARY_LOADER_IS_REF_COUNTED/p_library_loader_is_ref_counted=PROCEDURE)
+!
+! plist.h
+!
+SYMBOL_VECTOR=(p_list_append=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_APPEND/p_list_append=PROCEDURE)
+SYMBOL_VECTOR=(p_list_remove=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_REMOVE/p_list_remove=PROCEDURE)
+SYMBOL_VECTOR=(p_list_foreach=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_FOREACH/p_list_foreach=PROCEDURE)
+SYMBOL_VECTOR=(p_list_free=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_FREE/p_list_free=PROCEDURE)
+SYMBOL_VECTOR=(p_list_last=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_LAST/p_list_last=PROCEDURE)
+SYMBOL_VECTOR=(p_list_length=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_LENGTH/p_list_length=PROCEDURE)
+SYMBOL_VECTOR=(p_list_prepend=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_PREPEND/p_list_prepend=PROCEDURE)
+SYMBOL_VECTOR=(p_list_reverse=PROCEDURE)
+SYMBOL_VECTOR=(P_LIST_REVERSE/p_list_reverse=PROCEDURE)
+!
+! pmain.h
+!
+SYMBOL_VECTOR=(p_libsys_init=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBSYS_INIT/p_libsys_init=PROCEDURE)
+SYMBOL_VECTOR=(p_libsys_init_full=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBSYS_INIT_FULL/p_libsys_init_full=PROCEDURE)
+SYMBOL_VECTOR=(p_libsys_shutdown=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBSYS_SHUTDOWN/p_libsys_shutdown=PROCEDURE)
+SYMBOL_VECTOR=(p_libsys_version=PROCEDURE)
+SYMBOL_VECTOR=(P_LIBSYS_VERSION/p_libsys_version=PROCEDURE)
+!
+! pmem.h
+!
+SYMBOL_VECTOR=(p_malloc=PROCEDURE)
+SYMBOL_VECTOR=(P_MALLOC/p_malloc=PROCEDURE)
+SYMBOL_VECTOR=(p_malloc0=PROCEDURE)
+SYMBOL_VECTOR=(P_MALLOC0/p_malloc0=PROCEDURE)
+SYMBOL_VECTOR=(p_realloc=PROCEDURE)
+SYMBOL_VECTOR=(P_REALLOC/p_realloc=PROCEDURE)
+SYMBOL_VECTOR=(p_free=PROCEDURE)
+SYMBOL_VECTOR=(P_FREE/p_free=PROCEDURE)
+SYMBOL_VECTOR=(p_mem_set_vtable=PROCEDURE)
+SYMBOL_VECTOR=(P_MEM_SET_VTABLE/p_mem_set_vtable=PROCEDURE)
+SYMBOL_VECTOR=(p_mem_restore_vtable=PROCEDURE)
+SYMBOL_VECTOR=(P_MEM_RESTORE_VTABLE/p_mem_restore_vtable=PROCEDURE)
+SYMBOL_VECTOR=(p_mem_mmap=PROCEDURE)
+SYMBOL_VECTOR=(P_MEM_MMAP/p_mem_mmap=PROCEDURE)
+SYMBOL_VECTOR=(p_mem_munmap=PROCEDURE)
+SYMBOL_VECTOR=(P_MEM_MUNMAP/p_mem_munmap=PROCEDURE)
+!
+! pmutex.h
+!
+SYMBOL_VECTOR=(p_mutex_new=PROCEDURE)
+SYMBOL_VECTOR=(P_MUTEX_NEW/p_mutex_new=PROCEDURE)
+SYMBOL_VECTOR=(p_mutex_lock=PROCEDURE)
+SYMBOL_VECTOR=(P_MUTEX_LOCK/p_mutex_lock=PROCEDURE)
+SYMBOL_VECTOR=(p_mutex_trylock=PROCEDURE)
+SYMBOL_VECTOR=(P_MUTEX_TRYLOCK/p_mutex_trylock=PROCEDURE)
+SYMBOL_VECTOR=(p_mutex_unlock=PROCEDURE)
+SYMBOL_VECTOR=(P_MUTEX_UNLOCK/p_mutex_unlock=PROCEDURE)
+SYMBOL_VECTOR=(p_mutex_free=PROCEDURE)
+SYMBOL_VECTOR=(P_MUTEX_FREE/p_mutex_free=PROCEDURE)
+!
+! pprocess.h
+!
+SYMBOL_VECTOR=(p_process_get_current_pid=PROCEDURE)
+SYMBOL_VECTOR=(P_PROCESS_GET_CURRENT_PID/p_process_get_current_pid=PROCEDURE)
+SYMBOL_VECTOR=(p_process_is_running=PROCEDURE)
+SYMBOL_VECTOR=(P_PROCESS_IS_RUNNING/p_process_is_running=PROCEDURE)
+!
+! prwlock.h
+!
+SYMBOL_VECTOR=(p_rwlock_new=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_NEW/p_rwlock_new=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_reader_lock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_READER_LOCK/p_rwlock_reader_lock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_reader_trylock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_READER_TRYLOCK/p_rwlock_reader_trylock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_reader_unlock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_READER_UNLOCK/p_rwlock_reader_unlock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_writer_lock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_WRITER_LOCK/p_rwlock_writer_lock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_writer_trylock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_WRITER_TRYLOCK/p_rwlock_writer_trylock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_writer_unlock=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_WRITER_UNLOCK/p_rwlock_writer_unlock=PROCEDURE)
+SYMBOL_VECTOR=(p_rwlock_free=PROCEDURE)
+SYMBOL_VECTOR=(P_RWLOCK_FREE/p_rwlock_free=PROCEDURE)
+!
+! psemaphore.h
+!
+SYMBOL_VECTOR=(p_semaphore_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SEMAPHORE_NEW/p_semaphore_new=PROCEDURE)
+SYMBOL_VECTOR=(p_semaphore_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(P_SEMAPHORE_TAKE_OWNERSHIP/p_semaphore_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(p_semaphore_acquire=PROCEDURE)
+SYMBOL_VECTOR=(P_SEMAPHORE_ACQUIRE/p_semaphore_acquire=PROCEDURE)
+SYMBOL_VECTOR=(p_semaphore_release=PROCEDURE)
+SYMBOL_VECTOR=(P_SEMAPHORE_RELEASE/p_semaphore_release=PROCEDURE)
+SYMBOL_VECTOR=(p_semaphore_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SEMAPHORE_FREE/p_semaphore_free=PROCEDURE)
+!
+! pshm.h
+!
+SYMBOL_VECTOR=(p_shm_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_NEW/p_shm_new=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_TAKE_OWNERSHIP/p_shm_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_FREE/p_shm_free=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_lock=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_LOCK/p_shm_lock=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_unlock=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_UNLOCK/p_shm_unlock=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_get_address=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_GET_ADDRESS/p_shm_get_address=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_get_size=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_GET_SIZE/p_shm_get_size=PROCEDURE)
+!
+! pshmbuffer.h
+!
+SYMBOL_VECTOR=(p_shm_buffer_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_NEW/p_shm_buffer_new=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_FREE/p_shm_buffer_free=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_TAKE_OWNERSHIP/p_shm_buffer_take_ownership=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_read=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_READ/p_shm_buffer_read=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_write=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_WRITE/p_shm_buffer_write=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_get_free_space=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_GET_FREE_SPACE/p_shm_buffer_get_free_space=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_get_used_space=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_GET_USED_SPACE/p_shm_buffer_get_used_space=PROCEDURE)
+SYMBOL_VECTOR=(p_shm_buffer_clear=PROCEDURE)
+SYMBOL_VECTOR=(P_SHM_BUFFER_CLEAR/p_shm_buffer_clear=PROCEDURE)
+!
+! psocket.h
+!
+SYMBOL_VECTOR=(p_socket_new_from_fd=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_NEW_FROM_FD/p_socket_new_from_fd=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_NEW/p_socket_new=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_fd=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_FD/p_socket_get_fd=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_family=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_FAMILY/p_socket_get_family=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_type=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_TYPE/p_socket_get_type=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_protocol=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_PROTOCOL/p_socket_get_protocol=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_keepalive=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_KEEPALIVE/p_socket_get_keepalive=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_blocking=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_BLOCKING/p_socket_get_blocking=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_listen_backlog=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_LISTEN_BACKLOG/p_socket_get_listen_backlog=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_timeout=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_TIMEOUT/p_socket_get_timeout=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_local_address=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_LOCAL_ADDRESS/p_socket_get_local_address=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_get_remote_address=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_GET_REMOTE_ADDRESS/p_socket_get_remote_address=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_is_connected=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_IS_CONNECTED/p_socket_is_connected=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_is_closed=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_IS_CLOSED/p_socket_is_closed=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_check_connect_result=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_CHECK_CONNECT_RESULT/p_socket_check_connect_result=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_set_keepalive=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SET_KEEPALIVE/p_socket_set_keepalive=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_set_blocking=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SET_BLOCKING/p_socket_set_blocking=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_set_listen_backlog=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SET_LISTEN_BACKLOG/p_socket_set_listen_backlog=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_set_timeout=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SET_TIMEOUT/p_socket_set_timeout=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_bind=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_BIND/p_socket_bind=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_connect=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_CONNECT/p_socket_connect=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_listen=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_LISTEN/p_socket_listen=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_accept=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ACCEPT/p_socket_accept=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_receive=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_RECEIVE/p_socket_receive=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_receive_from=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_RECEIVE_FROM/p_socket_receive_from=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_send=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SEND/p_socket_send=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_send_to=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SEND_TO/p_socket_send_to=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_close=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_CLOSE/p_socket_close=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_shutdown=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SHUTDOWN/p_socket_shutdown=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_FREE/p_socket_free=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_set_buffer_size=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_SET_BUFFER_SIZE/p_socket_set_buffer_size=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_io_condition_wait=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_IO_CONDITION_WAIT/p_socket_io_condition_wait=PROCEDURE)
+!
+! psocketaddress.h
+!
+SYMBOL_VECTOR=(p_socket_address_new_fr1g0bamc$=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_NEW_FR0V6PAD7$/p_socket_address_new_fr1g0bamc$=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_NEW/p_socket_address_new=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_new_any=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_NEW_ANY/p_socket_address_new_any=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_new_loopback=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_NEW_LOOPBACK/p_socket_address_new_loopback=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_to_native=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_TO_NATIVE/p_socket_address_to_native=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_na1kai9ab$=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_NA0SBOC5O$/p_socket_address_get_na1kai9ab$=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_family=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_FAMILY/p_socket_address_get_family=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_address=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_ADDRESS/p_socket_address_get_address=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_port=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_PORT/p_socket_address_get_port=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_flow_info=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_FLOW_INFO/p_socket_address_get_flow_info=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_get_scope_id=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_GET_SCOPE_ID/p_socket_address_get_scope_id=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_set_flow_info=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_SET_FLOW_INFO/p_socket_address_set_flow_info=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_set_scope_id=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_SET_SCOPE_ID/p_socket_address_set_scope_id=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_is_flo3bgg0hi$=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_IS_FLO1N1P65T$/p_socket_address_is_flo3bgg0hi$=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_is_sco2c7455c$=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_IS_SCO1COK854$/p_socket_address_is_sco2c7455c$=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_is_ipv3s9t3vi$=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_IS_IPV13UAVM5$/p_socket_address_is_ipv3s9t3vi$=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_is_any=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_IS_ANY/p_socket_address_is_any=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_is_loopback=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_IS_LOOPBACK/p_socket_address_is_loopback=PROCEDURE)
+SYMBOL_VECTOR=(p_socket_address_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SOCKET_ADDRESS_FREE/p_socket_address_free=PROCEDURE)
+!
+! pspinlock.h
+!
+SYMBOL_VECTOR=(p_spinlock_new=PROCEDURE)
+SYMBOL_VECTOR=(P_SPINLOCK_NEW/p_spinlock_new=PROCEDURE)
+SYMBOL_VECTOR=(p_spinlock_lock=PROCEDURE)
+SYMBOL_VECTOR=(P_SPINLOCK_LOCK/p_spinlock_lock=PROCEDURE)
+SYMBOL_VECTOR=(p_spinlock_trylock=PROCEDURE)
+SYMBOL_VECTOR=(P_SPINLOCK_TRYLOCK/p_spinlock_trylock=PROCEDURE)
+SYMBOL_VECTOR=(p_spinlock_unlock=PROCEDURE)
+SYMBOL_VECTOR=(P_SPINLOCK_UNLOCK/p_spinlock_unlock=PROCEDURE)
+SYMBOL_VECTOR=(p_spinlock_free=PROCEDURE)
+SYMBOL_VECTOR=(P_SPINLOCK_FREE/p_spinlock_free=PROCEDURE)
+!
+! pstring.h
+!
+SYMBOL_VECTOR=(p_strdup=PROCEDURE)
+SYMBOL_VECTOR=(P_STRDUP/p_strdup=PROCEDURE)
+SYMBOL_VECTOR=(p_strchomp=PROCEDURE)
+SYMBOL_VECTOR=(P_STRCHOMP/p_strchomp=PROCEDURE)
+SYMBOL_VECTOR=(p_strtok=PROCEDURE)
+SYMBOL_VECTOR=(P_STRTOK/p_strtok=PROCEDURE)
+SYMBOL_VECTOR=(p_strtod=PROCEDURE)
+SYMBOL_VECTOR=(P_STRTOD/p_strtod=PROCEDURE)
+!
+! ptimeprofiler.h
+!
+SYMBOL_VECTOR=(p_time_profiler_new=PROCEDURE)
+SYMBOL_VECTOR=(P_TIME_PROFILER_NEW/p_time_profiler_new=PROCEDURE)
+SYMBOL_VECTOR=(p_time_profiler_reset=PROCEDURE)
+SYMBOL_VECTOR=(P_TIME_PROFILER_RESET/p_time_profiler_reset=PROCEDURE)
+SYMBOL_VECTOR=(p_time_profiler_elapsed_usecs=PROCEDURE)
+SYMBOL_VECTOR=(P_TIME_PROFILER_ELAPSED_USECS/p_time_profiler_elapsed_usecs=PROCEDURE)
+SYMBOL_VECTOR=(p_time_profiler_free=PROCEDURE)
+SYMBOL_VECTOR=(P_TIME_PROFILER_FREE/p_time_profiler_free=PROCEDURE)
+!
+! ptree.h
+!
+SYMBOL_VECTOR=(p_tree_new=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_NEW/p_tree_new=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_new_with_data=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_NEW_WITH_DATA/p_tree_new_with_data=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_new_full=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_NEW_FULL/p_tree_new_full=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_insert=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_INSERT/p_tree_insert=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_remove=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_REMOVE/p_tree_remove=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_lookup=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_LOOKUP/p_tree_lookup=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_foreach=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_FOREACH/p_tree_foreach=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_clear=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_CLEAR/p_tree_clear=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_get_type=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_GET_TYPE/p_tree_get_type=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_get_nnodes=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_GET_NNODES/p_tree_get_nnodes=PROCEDURE)
+SYMBOL_VECTOR=(p_tree_free=PROCEDURE)
+SYMBOL_VECTOR=(P_TREE_FREE/p_tree_free=PROCEDURE)
+!
+! puthread.h
+!
+SYMBOL_VECTOR=(p_uthread_create_full=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_CREATE_FULL/p_uthread_create_full=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_create=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_CREATE/p_uthread_create=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_exit=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_EXIT/p_uthread_exit=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_join=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_JOIN/p_uthread_join=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_sleep=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_SLEEP/p_uthread_sleep=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_set_priority=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_SET_PRIORITY/p_uthread_set_priority=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_yield=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_YIELD/p_uthread_yield=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_current_id=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_CURRENT_ID/p_uthread_current_id=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_current=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_CURRENT/p_uthread_current=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_ideal_count=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_IDEAL_COUNT/p_uthread_ideal_count=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_ref=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_REF/p_uthread_ref=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_unref=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_UNREF/p_uthread_unref=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_local_new=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_LOCAL_NEW/p_uthread_local_new=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_local_free=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_LOCAL_FREE/p_uthread_local_free=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_get_local=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_GET_LOCAL/p_uthread_get_local=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_set_local=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_SET_LOCAL/p_uthread_set_local=PROCEDURE)
+SYMBOL_VECTOR=(p_uthread_replace_local=PROCEDURE)
+SYMBOL_VECTOR=(P_UTHREAD_REPLACE_LOCAL/p_uthread_replace_local=PROCEDURE)
diff --git a/3rdparty/plibsys/platforms/vms-general/vms_shorten_symbol.c b/3rdparty/plibsys/platforms/vms-general/vms_shorten_symbol.c
new file mode 100644
index 0000000..fbb6c5a
--- /dev/null
+++ b/3rdparty/plibsys/platforms/vms-general/vms_shorten_symbol.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2010 Craig A. Berry
+ * Copyright (c) 2016 Alexander Saprykin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* vms_shorten_symbol
+ *
+ * This program provides shortening of long symbols (> 31 characters) using the
+ * same mechanism as the OpenVMS C compiler. The basic procedure is to compute
+ * an AUTODIN II checksum of the entire symbol, encode the checksum in base32,
+ * and glue together a shortened symbol from the first 23 characters of the
+ * original symbol plus the encoded checksum appended. The output format is
+ * the same as that of the name mangler database, stored by default in
+ * [.CXX_REPOSITORY]CXX$DEMANGLER_DB.
+ *
+ * To obtain the same result as CC/NAMES=SHORTENED, run like so:
+ *
+ * $ mcr []vms_shorten_symbol "Please_forgive_this_absurdly_long_symbol_name"
+ * PLEASE_FORGIVE_THIS_ABS1ARO4QU$Please_forgive_this_absurdly_long_symbol_name
+ *
+ * To obtain the same result as CC/NAMES=(SHORTENED,AS_IS), pass a non-zero
+ * value as the second argument, like so:
+ *
+ * $ mcr []vms_shorten_symbol "Please_forgive_this_absurdly_long_symbol_name" 1
+ * Please_forgive_this_abs3rv8rnn$Please_forgive_this_absurdly_long_symbol_name
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __VMS
+# define UINT32 unsigned int
+#else
+# include <inttypes.h>
+# define UINT32 uint32_t
+#endif
+
+static UINT32 crc32 (const char *input_string);
+static UINT32 u32_to_base32 (UINT32 input, char *output);
+static UINT32 vms_shorten_symbol (const char *symbol, char *shortened, char as_is_flag);
+
+/*
+ * This routine implements the AUTODIN II polynomial.
+ */
+UINT32
+crc32 (const char *input_string)
+{
+
+ /*
+ * CRC code and data based partly on FreeBSD implementation, which
+ * notes:
+ *
+ * The crc32 functions and data was originally written by Spencer
+ * Garrett >s...@quick.com> and was cleaned from the PostgreSQL source
+ * tree via the files contrib/ltree/crc32.[ch]. No license was
+ * included, therefore it is assumed that this code is public
+ * domain. Attribution still noted.
+ *
+ * (I think they mean "gleaned" not "cleaned".)
+ */
+ static const UINT32 autodin_ii_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+ };
+
+ UINT32 crc = ~0UL;
+ char * c;
+
+ for (c = (char *) input_string; *c; ++c)
+ crc = (crc >> 8) ^ autodin_ii_table[(crc ^ *c) & 0xff];
+
+ return ~crc;
+}
+
+/*
+ * This is the RFC2938 variant of base32, not RFC3548, Crockford's, or
+ * other newer variant. It produces an 8-byte encoded character string
+ * (plus trailing null) from a 32-bit integer input.
+ */
+static UINT32
+u32_to_base32 (UINT32 input, char *output)
+{
+ static const char base32hex_table[32] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v'
+ };
+
+ int i;
+
+ /*
+ * Grab lowest 5 bits and look up conversion in table. Lather, rinse,
+ * repeat for 6, 5-bit chunks to accommodate 32 bits of input.
+ */
+ for (i = 0; i < 7; i++) {
+ output[6 - i] = base32hex_table[input & 0x1f];
+
+ /* Position to look at next 5. */
+ input >>= 5;
+ }
+
+ /* It's DEC, so use '$' not '=' to pad. */
+ output[7] = '$';
+ output[8] = '\0';
+
+ return 0;
+}
+
+static UINT32
+vms_shorten_symbol (const char *symbol, char *shortened, char as_is_flag)
+{
+ char b32str[9];
+ UINT32 crc;
+ char * c;
+
+ crc = crc32 (symbol);
+
+ /*
+ * The compiler does not use the inverted checksum, so we invert it
+ * back before encoding.
+ */
+ (void) u32_to_base32 (~crc, (char *) &b32str);
+
+ if (!as_is_flag) {
+ for (c = (char *) &b32str; *c; c++)
+ *c = toupper (*c);
+ }
+
+ sprintf (shortened, "%.23s%.8s\n", symbol, b32str);
+ shortened[31] = '\0';
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ char short_symbol[32];
+ char as_is_flag = 0;
+ char * c;
+ char * input_symbol;
+ int symlen;
+
+ if (argc < 2) {
+ fprintf (stderr, "Usage: %s <symbol name> [<AS_IS flag>]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 2)
+ as_is_flag = 1;
+
+ symlen = strlen (argv[1]);
+
+ if (symlen <= 31) {
+ printf ("No need for shorten symbol\n");
+ return EXIT_SUCCESS;
+ }
+
+ input_symbol = malloc (symlen + 1);
+
+ if (input_symbol == NULL)
+ return EXIT_FAILURE;
+
+ strncpy (input_symbol, argv[1], symlen);
+ input_symbol[symlen] = '\0';
+
+ if (!as_is_flag) {
+ for (c = input_symbol; *c; c++)
+ *c = toupper (*c);
+ }
+
+ vms_shorten_symbol (input_symbol, (char *) &short_symbol, as_is_flag);
+ printf ("%s%s\n", &short_symbol, argv[1]);
+ free (input_symbol);
+
+ return EXIT_SUCCESS;
+}
diff --git a/3rdparty/plibsys/platforms/win32-borland/platform.cmake b/3rdparty/plibsys/platforms/win32-borland/platform.cmake
new file mode 100644
index 0000000..564ae9a
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-borland/platform.cmake
@@ -0,0 +1,8 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_CFLAGS "-w-8065 -w-8008 -w-8057 -w-8059 -w-8066 -w-8004")
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win32-clang/platform.cmake b/3rdparty/plibsys/platforms/win32-clang/platform.cmake
new file mode 100644
index 0000000..bd115ff
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-clang/platform.cmake
@@ -0,0 +1,8 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_CFLAGS "-Wno-missing-braces -Wmissing-field-initializers")
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win32-gcc/platform.cmake b/3rdparty/plibsys/platforms/win32-gcc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-gcc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win32-icc/platform.cmake b/3rdparty/plibsys/platforms/win32-icc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-icc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win32-msvc/platform.cmake b/3rdparty/plibsys/platforms/win32-msvc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-msvc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win32-watcom/platform.cmake b/3rdparty/plibsys/platforms/win32-watcom/platform.cmake
new file mode 100644
index 0000000..ef5a855
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win32-watcom/platform.cmake
@@ -0,0 +1,11 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+if (NOT PLIBSYS_SIZEOF_VOID_P)
+ set (PLIBSYS_SIZEOF_VOID_P 4)
+endif()
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win64-clang/platform.cmake b/3rdparty/plibsys/platforms/win64-clang/platform.cmake
new file mode 100644
index 0000000..bd115ff
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win64-clang/platform.cmake
@@ -0,0 +1,8 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_CFLAGS "-Wno-missing-braces -Wmissing-field-initializers")
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win64-gcc/platform.cmake b/3rdparty/plibsys/platforms/win64-gcc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win64-gcc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win64-icc/platform.cmake b/3rdparty/plibsys/platforms/win64-icc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win64-icc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/platforms/win64-msvc/platform.cmake b/3rdparty/plibsys/platforms/win64-msvc/platform.cmake
new file mode 100644
index 0000000..05ac5d8
--- /dev/null
+++ b/3rdparty/plibsys/platforms/win64-msvc/platform.cmake
@@ -0,0 +1,7 @@
+set (PLIBSYS_THREAD_MODEL win)
+set (PLIBSYS_IPC_MODEL win)
+set (PLIBSYS_TIME_PROFILER_MODEL win)
+set (PLIBSYS_DIR_MODEL win)
+set (PLIBSYS_LIBRARYLOADER_MODEL win)
+
+set (PLIBSYS_PLATFORM_LINK_LIBRARIES ws2_32)
diff --git a/3rdparty/plibsys/scripts/run_tests.sh b/3rdparty/plibsys/scripts/run_tests.sh
new file mode 100755
index 0000000..e6faada
--- /dev/null
+++ b/3rdparty/plibsys/scripts/run_tests.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+#
+# The MIT License
+#
+# Copyright 2017-2018, Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+#===========================================================================
+
+if [[ $# -ne 2 ]]; then
+ echo "Usage: run_tests.sh <testing_dir> <shared_library>"
+ echo "Where: <testing_dir> is a directory containing tests to run"
+ echo " <shared_library> is a path to the shared library to be tested"
+ exit 1
+fi
+
+total_counter=0
+pass_counter=0
+
+IFS=$'\n'
+files=$(ls $1)
+
+export LD_LIBRARY_PATH=$1:$LD_LIBRARY_PATH
+
+selfname=$(basename $0)
+
+echo "Running tests..."
+
+for file in $files
+do
+ if [[ $file == *"_test"* && $file != $selfname ]]; then
+ test_name=${file%.*}
+ total_counter=$((total_counter + 1))
+ echo "[RUN ] $test_name"
+
+ if [[ $test_name == "plibraryloader_test" ]]; then
+ $($1/${file} $2 > /dev/null 2>&1)
+ else
+ $($1/${file} > /dev/null 2>&1)
+ fi
+
+ if [[ $? -ne 0 ]]; then
+ echo "[FAIL] *** Test failed: $test_name"
+ else
+ echo "[PASS] Test passed: $test_name"
+ pass_counter=$((pass_counter + 1))
+ fi
+ fi
+done
+
+echo "Tests passed: $pass_counter/$total_counter"
diff --git a/3rdparty/plibsys/src/CMakeLists.txt b/3rdparty/plibsys/src/CMakeLists.txt
new file mode 100644
index 0000000..2f13fbf
--- /dev/null
+++ b/3rdparty/plibsys/src/CMakeLists.txt
@@ -0,0 +1,996 @@
+# The MIT License
+#
+# Copyright (C) 2018-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+if (POLICY CMP0075)
+ cmake_policy (SET CMP0075 NEW)
+endif()
+
+include (CheckCSourceCompiles)
+include (CheckTypeSize)
+include (CheckIncludeFile)
+include (TestBigEndian)
+
+# First of all, detect size of the pointer for the target machine.
+# We can't rely on CMAKE_SIZEOF_VOID_P when building universal
+# binaries.
+
+check_type_size ("void *" PLIBSYS_SIZEOF_VOID_P)
+check_type_size ("size_t" PLIBSYS_SIZEOF_SIZE_T)
+check_type_size ("long" PLIBSYS_SIZEOF_LONG)
+
+# Without generated code multi-arch builds are not supported anyway,
+# so the best we can do is to fallback to detected size values
+
+if (CMAKE_VERSION VERSION_LESS 2.8.1)
+ set (PLIBSYS_SIZEOF_VOID_P_CODE "#define PLIBSYS_SIZEOF_VOID_P ${PLIBSYS_SIZEOF_VOID_P}")
+ set (PLIBSYS_SIZEOF_SIZE_T_CODE "#define PLIBSYS_SIZEOF_SIZE_T ${PLIBSYS_SIZEOF_SIZE_T}")
+ set (PLIBSYS_SIZEOF_LONG_CODE "#define PLIBSYS_SIZEOF_LONG ${PLIBSYS_SIZEOF_LONG}")
+endif()
+
+include (${PROJECT_SOURCE_DIR}/cmake/PlatformDetect.cmake)
+include (${PROJECT_SOURCE_DIR}/cmake/VisibilityDetect.cmake)
+include (${PROJECT_SOURCE_DIR}/cmake/StdargDetect.cmake)
+include (${PROJECT_SOURCE_DIR}/cmake/ThreadNameDetect.cmake)
+set (OUTPUT_DIR ${CMAKE_BINARY_DIR})
+
+# Try to detect target platform
+plibsys_detect_target_platform (PLIBSYS_TARGET_PLATFORM)
+plibsys_detect_c_compiler (PLIBSYS_C_COMPILER)
+plibsys_detect_target_os (PLIBSYS_TARGET_OS)
+plibsys_detect_os_bits (PLIBSYS_OS_BITS)
+
+if (PLIBSYS_OS_BITS STREQUAL "unknown")
+ message (FATAL_ERROR "Failed to detect bitness of the target system")
+endif()
+
+if ((PLIBSYS_TARGET_OS STREQUAL windows) AND NOT (PLIBSYS_TARGET_OS STREQUAL cygwin)
+ AND NOT (PLIBSYS_TARGET_OS STREQUAL msys))
+ set (PLIBSYS_NATIVE_WINDOWS TRUE)
+endif()
+
+if (PLIBSYS_COVERAGE)
+ if (PLIBSYS_C_COMPILER MATCHES "gcc|clang")
+ set (CMAKE_BUILD_TYPE "Debug")
+ list (APPEND CMAKE_C_FLAGS "--coverage")
+ endif()
+endif()
+
+# CMP0042, see http://www.cmake.org/Wiki/CMake_RPATH_handling
+if (PLIBSYS_TARGET_OS STREQUAL darwin)
+ if (POLICY CMP0068)
+ cmake_policy (SET CMP0068 NEW)
+ endif()
+
+ set (CMAKE_MACOSX_RPATH TRUE)
+ set (CMAKE_SKIP_BUILD_RPATH FALSE)
+
+ # Fix runtime paths on macOS 10.5 and less
+ if (CMAKE_SYSTEM_VERSION VERSION_LESS "10.0.0")
+ set (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+ else()
+ set (CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+ endif()
+
+ set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+ set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+ list (FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
+
+ if ("${isSystemDir}" STREQUAL "-1")
+ set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+ endif ("${isSystemDir}" STREQUAL "-1")
+endif()
+
+if (NOT EXISTS "${PROJECT_SOURCE_DIR}/platforms/${PLIBSYS_TARGET_PLATFORM}/")
+ message (FATAL_ERROR "plibsys doesn't support unknown platform ${PLIBSYS_TARGET_PLATFORM}")
+endif()
+
+include (${PROJECT_SOURCE_DIR}/platforms/${PLIBSYS_TARGET_PLATFORM}/platform.cmake)
+
+set (PLIBSYS_INCLUDE_DIRS
+ ${PROJECT_SOURCE_DIR}/src
+ ${CMAKE_BINARY_DIR}
+)
+
+set (PLIBSYS_PUBLIC_HDRS
+ patomic.h
+ ptypes.h
+ pmacros.h
+ pmacroscompiler.h
+ pmacroscpu.h
+ pmacrosos.h
+ pcondvariable.h
+ pcryptohash.h
+ perror.h
+ perrortypes.h
+ pdir.h
+ pfile.h
+ phashtable.h
+ pinifile.h
+ plibsys.h
+ plibraryloader.h
+ plist.h
+ pmain.h
+ pmem.h
+ pmutex.h
+ pprocess.h
+ prwlock.h
+ psemaphore.h
+ pshm.h
+ pshmbuffer.h
+ psocket.h
+ psocketaddress.h
+ pspinlock.h
+ pstdarg.h
+ pstring.h
+ ptimeprofiler.h
+ ptree.h
+ puthread.h
+)
+
+set (PLIBSYS_PRIVATE_HDRS
+ pcryptohash-gost3411.h
+ pcryptohash-md5.h
+ pcryptohash-sha1.h
+ pcryptohash-sha2-256.h
+ pcryptohash-sha2-512.h
+ pcryptohash-sha3.h
+ perror-private.h
+ plibsys-private.h
+ psysclose-private.h
+ ptimeprofiler-private.h
+ ptree-avl.h
+ ptree-bst.h
+ ptree-rb.h
+ ptree-private.h
+ puthread-private.h
+ ${CMAKE_BINARY_DIR}/plibsysconfig.h
+)
+
+set (PLIBSYS_SRCS
+ pcryptohash.c
+ pcryptohash-gost3411.c
+ pcryptohash-md5.c
+ pcryptohash-sha1.c
+ pcryptohash-sha2-256.c
+ pcryptohash-sha2-512.c
+ pcryptohash-sha3.c
+ pdir.c
+ perror.c
+ pfile.c
+ phashtable.c
+ pinifile.c
+ plist.c
+ pmain.c
+ pmem.c
+ pprocess.c
+ pshmbuffer.c
+ psocket.c
+ psocketaddress.c
+ pstring.c
+ ptimeprofiler.c
+ ptree.c
+ ptree-avl.c
+ ptree-bst.c
+ ptree-rb.c
+ puthread.c
+)
+
+if (PLIBSYS_NATIVE_WINDOWS)
+ set (PLIBSYS_CLOSE_MODEL win)
+elseif (PLIBSYS_TARGET_OS STREQUAL darwin)
+ set (PLIBSYS_CLOSE_MODEL darwin)
+else()
+ set (PLIBSYS_CLOSE_MODEL unix)
+endif()
+
+if (PLIBSYS_THREAD_MODEL STREQUAL "")
+ set (PLIBSYS_THREAD_MODEL none)
+endif()
+
+if (PLIBSYS_IPC_MODEL STREQUAL "")
+ set (PLIBSYS_IPC_MODEL none)
+endif()
+
+if (PLIBSYS_TIME_PROFILER_MODEL STREQUAL "")
+ set (PLIBSYS_TIME_PROFILER_MODEL generic)
+endif()
+
+if (PLIBSYS_DIR_MODEL STREQUAL "")
+ set (PLIBSYS_DIR_MODEL none)
+endif()
+
+if (PLIBSYS_LIBRARYLOADER_MODEL STREQUAL "")
+ set (PLIBSYS_LIBRARYLOADER_MODEL none)
+endif()
+
+set (PLIBSYS_PLATFORM_SRCS
+ pcondvariable-${PLIBSYS_THREAD_MODEL}.c
+ pmutex-${PLIBSYS_THREAD_MODEL}.c
+ psemaphore-${PLIBSYS_IPC_MODEL}.c
+ pshm-${PLIBSYS_IPC_MODEL}.c
+ psysclose-${PLIBSYS_CLOSE_MODEL}.c
+ puthread-${PLIBSYS_THREAD_MODEL}.c
+ ptimeprofiler-${PLIBSYS_TIME_PROFILER_MODEL}.c
+ pdir-${PLIBSYS_DIR_MODEL}.c
+ plibraryloader-${PLIBSYS_LIBRARYLOADER_MODEL}.c
+)
+
+if (NOT PLIBSYS_IPC_MODEL STREQUAL none)
+ list (APPEND PLIBSYS_PRIVATE_HDRS pipc-private.h)
+ list (APPEND PLIBSYS_SRCS pipc.c)
+endif()
+
+# Save compiler flags
+set (SAVED_CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
+set (SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+set (SAVED_CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS})
+
+list (APPEND CMAKE_REQUIRED_DEFINITIONS ${PLIBSYS_PLATFORM_DEFINES})
+list (APPEND CMAKE_REQUIRED_LIBRARIES ${PLIBSYS_PLATFORM_LINK_LIBRARIES})
+list (APPEND CMAKE_REQUIRED_FLAGS ${PLIBSYS_PLATFORM_LDFLAGS})
+
+set (PLIBSYS_ATOMIC_LOCK_FREE FALSE)
+
+if (NOT PLIBSYS_ATOMIC_MODEL)
+ message (STATUS "Checking for lock-free atomic intrinsics")
+
+ if (NOT PLIBSYS_C_COMPILER STREQUAL clang)
+ # GCC __atomic* intrinsics
+ check_c_source_compiles (
+ "int main () {
+ int i, tmp_int = 0;
+ void *ptr, *tmp_ptr = 0;
+ __atomic_store_4 (&i, 0, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n (&i, &tmp_int, 1, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n ((unsigned long long *) &ptr,
+ (unsigned long long *) &tmp_ptr,
+ (unsigned long long) 1, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_fetch_add (&i, 1, __ATOMIC_SEQ_CST);
+ return 0;
+ }"
+ PLIBSYS_ATOMIC_IMPL_GCCATOMIC
+ )
+
+ if (PLIBSYS_ATOMIC_IMPL_GCCATOMIC)
+ set (PLIBSYS_ATOMIC_LOCK_FREE yes)
+ set (PLIBSYS_ATOMIC_MODEL "c11")
+ endif()
+ endif()
+
+ # GCC __sync* intinsics
+ if (NOT PLIBSYS_ATOMIC_LOCK_FREE)
+ check_c_source_compiles (
+ "int main () {
+ int i;
+ __sync_synchronize ();
+ __sync_val_compare_and_swap (&i, 0, 1);
+ __sync_fetch_and_add (&i, 1);
+ return 0;
+ }"
+ PLIBSYS_ATOMIC_IMPL_GCCSYNC
+ )
+
+ if (PLIBSYS_ATOMIC_IMPL_GCCSYNC)
+ set (PLIBSYS_ATOMIC_LOCK_FREE yes)
+ set (PLIBSYS_ATOMIC_MODEL "sync")
+ endif()
+ endif()
+
+ if (NOT PLIBSYS_ATOMIC_LOCK_FREE)
+ if (PLIBSYS_TARGET_OS STREQUAL windows AND (PLIBSYS_C_COMPILER STREQUAL borland OR
+ PLIBSYS_C_COMPILER STREQUAL watcom OR
+ PLIBSYS_C_COMPILER STREQUAL icc OR
+ PLIBSYS_C_COMPILER STREQUAL msvc))
+ set (PLIBSYS_ATOMIC_LOCK_FREE TRUE)
+ set (PLIBSYS_ATOMIC_MODEL "win")
+ else()
+ set (PLIBSYS_ATOMIC_LOCK_FREE FALSE)
+ set (PLIBSYS_ATOMIC_MODEL "sim")
+ endif()
+ endif()
+
+ if (PLIBSYS_ATOMIC_LOCK_FREE)
+ message (STATUS "Checking for lock-free atomic intrinsics - works")
+ else()
+ message (STATUS "Checking for lock-free atomic intrinsics - not works")
+ endif()
+endif()
+
+list (APPEND PLIBSYS_SRCS
+ patomic-${PLIBSYS_ATOMIC_MODEL}.c
+ pspinlock-${PLIBSYS_ATOMIC_MODEL}.c
+)
+
+if (EXISTS PLIBSYS_CONFIG_FILE)
+ file (REMOVE ${PLIBSYS_CONFIG_FILE})
+endif()
+
+test_big_endian (PLIBSYS_IS_BIGENDIAN)
+
+check_include_file ("float.h" PLIBSYS_HAVE_FLOAT_H)
+check_include_file ("values.h" PLIBSYS_HAVE_VALUES_H)
+check_include_file ("limits.h" PLIBSYS_HAVE_LIMITS_H)
+
+if (PLIBSYS_HAVE_FLOAT_H)
+ set (PLIBSYS_NEED_FLOAT_H TRUE)
+ set (PLIBSYS_FLOAT_MIN FLT_MIN)
+ set (PLIBSYS_FLOAT_MAX FLT_MAX)
+ set (PLIBSYS_DOUBLE_MIN DBL_MIN)
+ set (PLIBSYS_DOUBLE_MAX DBL_MAX)
+elseif (PLIBSYS_HAVE_VALUES_H)
+ set (PLIBSYS_NEED_VALUES_H TRUE)
+ set (PLIBSYS_FLOAT_MIN MINFLOAT)
+ set (PLIBSYS_FLOAT_MAX MAXFLOAT)
+ set (PLIBSYS_DOUBLE_MIN MINDOUBLE)
+ set (PLIBSYS_DOUBLE_MAX MAXDOUBLE)
+endif()
+
+if (PLIBSYS_HAVE_LIMITS_H)
+ set (PLIBSYS_NEED_LIMITS_H TRUE)
+ set (PLIBSYS_SHORT_MIN SHRT_MIN)
+ set (PLIBSYS_SHORT_MAX SHRT_MAX)
+ set (PLIBSYS_USHORT_MAX USHRT_MAX)
+ set (PLIBSYS_INT_MIN INT_MIN)
+ set (PLIBSYS_INT_MAX INT_MAX)
+ set (PLIBSYS_UINT_MAX UINT_MAX)
+ set (PLIBSYS_LONG_MIN LONG_MIN)
+ set (PLIBSYS_LONG_MAX LONG_MAX)
+ set (PLIBSYS_ULONG_MAX ULONG_MAX)
+elseif (PLIBSYS_HAVE_VALUES_H)
+ set (PLIBSYS_NEED_VALUES_H TRUE)
+ set (PLIBSYS_SHORT_MIN MINSHORT)
+ set (PLIBSYS_SHORT_MAX MAXSHORT)
+ set (PLIBSYS_USHORT_MAX "(((pushort) P_MAXSHORT) * 2 + 1)")
+ set (PLIBSYS_INT_MIN MININT)
+ set (PLIBSYS_INT_MAX MAXINT)
+ set (PLIBSYS_UINT_MAX "(((puint) P_MAXINT) * 2 + 1)")
+ set (PLIBSYS_LONG_MIN MINLONG)
+ set (PLIBSYS_LONG_MAX MAXLONG)
+ set (PLIBSYS_ULONG_MAX "(((pulong) P_MAXLONG) * 2 + 1)")
+endif()
+
+if (PLIBSYS_NATIVE_WINDOWS)
+ set (PLIBSYS_NEED_WINDOWS_H TRUE)
+endif()
+
+if (NOT PLIBSYS_NATIVE_WINDOWS)
+ # Check for anonymous mmap()
+ message (STATUS "Checking whether mmap has anonymous mapping")
+
+ check_c_source_compiles (
+ "#include <sys/types.h>
+ #include <sys/mman.h>
+ int main () {
+ mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ return 0;
+ }"
+ PLIBSYS_MMAP_HAS_MAP_ANON
+ )
+
+ check_c_source_compiles (
+ "#include <sys/types.h>
+ #include <sys/mman.h>
+ int main () {
+ mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ return 0;
+ }"
+ PLIBSYS_MMAP_HAS_MAP_ANONYMOUS
+ )
+
+ if (PLIBSYS_MMAP_HAS_MAP_ANONYMOUS OR PLIBSYS_MMAP_HAS_MAP_ANON)
+ message (STATUS "Checking whether mmap has anonymous mapping - yes")
+ else()
+ message (STATUS "Checking whether mmap has anonymous mapping - no")
+ endif()
+
+ if (PLIBSYS_MMAP_HAS_MAP_ANONYMOUS)
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_MMAP_HAS_MAP_ANONYMOUS)
+ elseif (PLIBSYS_MMAP_HAS_MAP_ANON)
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_MMAP_HAS_MAP_ANON)
+ endif()
+
+ # Check for clock_nanosleep() call
+ message (STATUS "Checking whether clock_nanosleep() presents")
+
+ check_c_source_compiles (
+ "#include <time.h>
+ int main () {
+ struct timespec time_sp = {0, 500000000L};
+ clock_nanosleep (CLOCK_MONOTONIC, 0, &time_sp, NULL);
+ return 0;
+ }"
+ PLIBSYS_HAS_CLOCKNANOSLEEP
+ )
+
+ if (PLIBSYS_HAS_CLOCKNANOSLEEP)
+ message (STATUS "Checking whether clock_nanosleep() presents - yes")
+ else()
+ message (STATUS "Checking whether clock_nanosleep() presents - no")
+ endif()
+
+ # Check for nanosleep() call
+ message (STATUS "Checking whether nanosleep() presents")
+
+ check_c_source_compiles (
+ "#include <time.h>
+ int main () {
+ struct timespec time_sp = {0, 500000000L};
+ nanosleep (&time_sp, NULL);
+ return 0;
+ }"
+ PLIBSYS_HAS_NANOSLEEP
+ )
+
+ if (PLIBSYS_HAS_NANOSLEEP)
+ message (STATUS "Checking whether nanosleep() presents - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_NANOSLEEP)
+ else()
+ message (STATUS "Checking whether nanosleep() presents - no")
+ endif()
+
+ # Prefere clock_nanosleep() over nanosleep() for power consumption
+ if (PLIBSYS_HAS_CLOCKNANOSLEEP)
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_CLOCKNANOSLEEP)
+ elseif(PLIBSYS_HAS_NANOSLEEP)
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_NANOSLEEP)
+ endif()
+
+ # Check for getaddrinfo() call
+ message (STATUS "Checking whether getaddrinfo() presents")
+
+ check_c_source_compiles (
+ "#include <sys/socket.h>
+ #include <netdb.h>
+ int main () {
+ getaddrinfo (0, 0, 0, 0);
+ freeaddrinfo (0);
+
+ return 0;
+ }"
+ PLIBSYS_HAS_GETADDRINFO
+ )
+
+ if (PLIBSYS_HAS_GETADDRINFO)
+ message (STATUS "Checking whether getaddrinfo() presents - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_GETADDRINFO)
+ else()
+ message (STATUS "Checking whether getaddrinfo() presents - no")
+ endif()
+endif()
+
+if (NOT PLIBSYS_RWLOCK_MODEL)
+ set (PLIBSYS_RWLOCK_MODEL ${PLIBSYS_THREAD_MODEL})
+else()
+ if (NOT PLIBSYS_RWLOCK_MODEL STREQUAL general AND
+ NOT PLIBSYS_RWLOCK_MODEL STREQUAL none)
+ message (WARNING "It's not recommended to mix threading and read-write lock models")
+ endif()
+endif()
+
+if (PLIBSYS_THREAD_MODEL STREQUAL posix)
+ # Some systems only need the difinition to be available
+ if (PLIBSYS_TARGET_OS MATCHES "darwin|aix")
+ set (PLIBSYS_SCHED_CHECK "defined (_POSIX_THREAD_PRIORITY_SCHEDULING)")
+ elseif (PLIBSYS_TARGET_OS STREQUAL android)
+ set (PLIBSYS_SCHED_CHECK "0")
+ else()
+ set (PLIBSYS_SCHED_CHECK "defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING - 0 >= 0)")
+ endif()
+
+ # Check for thread scheduling
+ message (STATUS "Checking whether POSIX thread scheduling presents")
+
+ check_c_source_compiles (
+ "#include <unistd.h>
+ #include <pthread.h>
+ #include <sched.h>
+
+ int main () {
+ #if ${PLIBSYS_SCHED_CHECK}
+ sched_get_priority_min (0);
+ sched_get_priority_max (0);
+ #else
+ stop_compile_here
+ #endif
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_SCHEDULING
+ )
+
+ if (PLIBSYS_HAS_POSIX_SCHEDULING)
+ message (STATUS "Checking whether POSIX thread scheduling presents - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_POSIX_SCHEDULING)
+ else()
+ message (STATUS "Checking whether POSIX thread scheduling presents - no")
+ endif()
+
+ # Check for thread stack size
+ message (STATUS "Checking whether POSIX thread stack size is supported")
+
+ check_c_source_compiles (
+ "#include <pthread.h>
+
+ int main () {
+ pthread_attr_t attr;
+
+ pthread_attr_setstacksize (&attr, 0);
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_STACKSIZE
+ )
+
+ if (PLIBSYS_HAS_POSIX_STACKSIZE)
+ message (STATUS "Checking whether POSIX thread stack size is supported - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_POSIX_STACKSIZE)
+ else()
+ message (STATUS "Checking whether POSIX thread stack size is supported - no")
+ endif()
+endif()
+
+# Some platforms may have headers, but lack actual implementation,
+# thus we can let platform to override read-write lock model with
+# general implementation
+if (PLIBSYS_THREAD_MODEL STREQUAL posix AND
+ PLIBSYS_RWLOCK_MODEL STREQUAL posix)
+ # Check for read-write lock support
+ message (STATUS "Checking whether POSIX read-write locks are supported")
+
+ check_c_source_compiles (
+ "#include <pthread.h>
+
+ int main () {
+ pthread_rwlock_t rwl;
+
+ pthread_rwlock_init (&rwl, 0);
+ pthread_rwlock_destroy (&rwl);
+ return 0;
+ }"
+ PLIBSYS_HAS_POSIX_RWLOCK
+ )
+
+ if (PLIBSYS_HAS_POSIX_RWLOCK)
+ message (STATUS "Checking whether POSIX read-write locks are supported - yes")
+ else()
+ message (STATUS "Checking whether POSIX read-write locks are supported - no")
+ set (PLIBSYS_RWLOCK_MODEL "general")
+ endif()
+endif()
+
+list (APPEND PLIBSYS_PLATFORM_SRCS prwlock-${PLIBSYS_RWLOCK_MODEL}.c)
+
+# POSIX thread naming functions
+check_c_source_compiles (
+ "#include <pthread.h>
+ #include <pthread_np.h>
+
+ int main () {return 0;}"
+ PLIBSYS_HAS_PTHREAD_NP
+ )
+
+if(PLIBSYS_HAS_PTHREAD_NP)
+ set (PLIBSYS_NEED_PTHREAD_NP_H TRUE)
+else()
+ set (PLIBSYS_NEED_PTHREAD_NP_H FALSE)
+endif()
+
+message (STATUS "Checking whether POSIX thread names are supported")
+
+plibsys_detect_thread_name (PLIBSYS_NEED_PTHREAD_NP_H PLIBSYS_THREADNAME_DEF)
+
+if (NOT PLIBSYS_THREADNAME_DEF STREQUAL "NONE")
+ list (APPEND PLIBSYS_COMPILE_DEFS -D${PLIBSYS_THREADNAME_DEF})
+endif()
+
+if (PLIBSYS_THREADNAME_DEF STREQUAL "NONE")
+ message (STATUS "Checking whether POSIX thread names are supported - no")
+else()
+ message (STATUS "Checking whether POSIX thread names are supported - yes")
+endif()
+
+# Windows sockets
+if (PLIBSYS_NATIVE_WINDOWS)
+ set (PLIBSYS_SOCKET_INCLUDES "#include <winsock2.h>
+ #include <ws2tcpip.h>
+ #include <windows.h>")
+else()
+ set (PLIBSYS_SOCKET_INCLUDES "#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>")
+endif()
+
+# Check for socklen_t definition
+message (STATUS "Checking whether socklen_t is defined")
+
+check_c_source_compiles (
+ "${PLIBSYS_SOCKET_INCLUDES}
+ int main () {
+ socklen_t len = sizeof (socklen_t);
+ return len > 0 ? 0 : -1;
+ }"
+ PLIBSYS_HAS_SOCKLEN_T
+ )
+
+if (PLIBSYS_HAS_SOCKLEN_T)
+ message (STATUS "Checking whether socklen_t is defined - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_SOCKLEN_T)
+else()
+ message (STATUS "Checking whether socklen_t is defined - no")
+endif()
+
+# Check for sockaddr_storage structure
+message (STATUS "Checking whether struct sockaddr_storage is defined")
+
+check_c_source_compiles (
+ "${PLIBSYS_SOCKET_INCLUDES}
+ int main () {
+ struct sockaddr_storage sock_addr;
+ sock_addr.ss_family = AF_INET;
+
+ return 0;
+ }"
+ PLIBSYS_HAS_SOCKADDR_STORAGE
+ )
+
+if (PLIBSYS_HAS_SOCKADDR_STORAGE)
+ message (STATUS "Checking whether struct sockaddr_storage is defined - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_SOCKADDR_STORAGE)
+else()
+ message (STATUS "Checking whether struct sockaddr_storage is defined - no")
+endif()
+
+# Check sa_len field in struct sockaddr
+message (STATUS "Checking whether struct sockaddr has sa_len")
+
+check_c_source_compiles (
+ "${PLIBSYS_SOCKET_INCLUDES}
+ int main () {
+ struct sockaddr sock_addr;
+ sock_addr.sa_len = 0;
+
+ return 0;
+ }"
+ PLIBSYS_SOCKADDR_HAS_SA_LEN
+ )
+
+if (PLIBSYS_SOCKADDR_HAS_SA_LEN)
+ message (STATUS "Checking whether struct sockaddr has sa_len - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_SOCKADDR_HAS_SA_LEN)
+else()
+ message (STATUS "Checking whether struct sockaddr has sa_len - no")
+endif()
+
+# Check sin6_scope_id field in struct sockaddr_in6
+message (STATUS "Checking whether struct sockaddr_in6 has sin6_scope_id")
+
+check_c_source_compiles (
+ "${PLIBSYS_SOCKET_INCLUDES}
+ int main () {
+ struct sockaddr_in6 sock_addr;
+ sock_addr.sin6_scope_id = 0;
+
+ return 0;
+ }"
+ PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID
+ )
+
+if (PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID)
+ message (STATUS "Checking whether struct sockaddr_in6 has sin6_scope_id - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_SOCKADDR_IN6_HAS_SCOPEID)
+else()
+ message (STATUS "Checking whether struct sockaddr_in6 has sin6_scope_id - no")
+endif()
+
+# Check sin6_flowinfo field in struct sockaddr_in6
+message (STATUS "Checking whether struct sockaddr_in6 has sin6_flowinfo")
+
+check_c_source_compiles (
+ "${PLIBSYS_SOCKET_INCLUDES}
+ int main () {
+ struct sockaddr_in6 sock_addr;
+ sock_addr.sin6_flowinfo = 0;
+
+ return 0;
+ }"
+ PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO
+ )
+
+if (PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO)
+ message (STATUS "Checking whether struct sockaddr_in6 has sin6_flowinfo - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO)
+else()
+ message (STATUS "Checking whether struct sockaddr_in6 has sin6_flowinfo - no")
+endif()
+
+# Check sa_family_t type size in struct sockaddr
+set (CMAKE_EXTRA_INCLUDE_FILES_OLD ${CMAKE_EXTRA_INCLUDE_FILES})
+
+if (PLIBSYS_NATIVE_WINDOWS)
+ set (CMAKE_EXTRA_INCLUDE_FILES
+ winsock2.h
+ ws2tcpip.h
+ windows.h
+ )
+else()
+ set (CMAKE_EXTRA_INCLUDE_FILES
+ sys/types.h
+ sys/socket.h
+ netinet/in.h
+ )
+endif()
+
+check_type_size ("((struct sockaddr *) 0)->sa_family" PLIBSYS_SIZEOF_SAFAMILY_T LANGUAGE C)
+
+set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES_OLD})
+
+# Check for lldiv() call
+message (STATUS "Checking whether lldiv() presents")
+
+check_c_source_compiles (
+ "#define __USE_ISOC99
+ #include <stdlib.h>
+ int main () {
+ lldiv_t res = lldiv (100LL, 13LL);
+ res.quot = 0;
+ res.rem = 0;
+
+ return 0;
+ }"
+ PLIBSYS_HAS_LLDIV
+ )
+
+if (PLIBSYS_HAS_LLDIV)
+ message (STATUS "Checking whether lldiv() presents - yes")
+ list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_HAS_LLDIV)
+else()
+ message (STATUS "Checking whether lldiv() presents - no")
+endif()
+
+# Symbols visibility attributes
+if (PLIBSYS_VISIBILITY)
+ message (STATUS "Checking whether compiler supports visibility")
+ plibsys_detect_visibility (PLIBSYS_VISIBILITY_CFLAGS PLIBSYS_VISIBILITY_LDFLAGS)
+
+ if (NOT PLIBSYS_VISIBILITY_CFLAGS AND NOT PLIBSYS_VISIBILITY_LDFLAGS)
+ message (STATUS "Checking whether compiler supports visibility - no")
+ set (PLIBSYS_VISIBILITY OFF)
+ else()
+ message (STATUS "Checking whether compiler supports visibility - yes")
+
+ if (PLIBSYS_VISIBILITY_CFLAGS)
+ list (APPEND PLIBSYS_PLATFORM_CFLAGS ${PLIBSYS_VISIBILITY_CFLAGS})
+ endif()
+
+ if (PLIBSYS_VISIBILITY_LDFLAGS)
+ list (APPEND PLIBSYS_PLATFORM_LDFLAGS ${PLIBSYS_VISIBILITY_LDFLAGS})
+ endif()
+ endif()
+endif()
+
+# Variable arguments
+check_include_file ("stdarg.h" PLIBSYS_HAVE_STDARG_H)
+
+if (NOT PLIBSYS_HAVE_STDARG_H)
+ message (FATAL_ERROR "Support for <stdarg.h> is required for target plarform, not found")
+endif()
+
+plibsys_detect_va_copy (PLIBSYS_VA_COPY)
+
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/plibsysconfig.h.in ${CMAKE_BINARY_DIR}/plibsysconfig.h)
+
+# Restore compiler flags
+set (CMAKE_REQUIRED_DEFINITIONS ${SAVED_CMAKE_REQUIRED_DEFINITIONS})
+set (CMAKE_REQUIRED_LIBRARIES ${SAVED_CMAKE_REQUIRED_LIBRARIES})
+set (SAVED_CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS})
+
+# Disable useless warnings
+if (MSVC)
+ list (APPEND PLIBSYS_COMPILE_DEFS -D_CRT_SECURE_NO_WARNINGS)
+ list (APPEND PLIBSYS_COMPILE_DEFS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
+endif()
+
+# Prepare compile definitions
+list (APPEND PLIBSYS_COMPILE_DEFS -DPLIBSYS_COMPILATION)
+
+if (PLIBSYS_PLATFORM_DEFINES)
+ list (APPEND PLIBSYS_COMPILE_DEFS ${PLIBSYS_PLATFORM_DEFINES})
+endif()
+
+# Add targets
+add_library (plibsys SHARED ${PLIBSYS_SRCS} ${PLIBSYS_PLATFORM_SRCS} ${PLIBSYS_PUBLIC_HDRS} ${PLIBSYS_PRIVATE_HDRS})
+
+if (PLIBSYS_BUILD_STATIC)
+ add_library (plibsysstatic STATIC ${PLIBSYS_SRCS} ${PLIBSYS_PLATFORM_SRCS} ${PLIBSYS_PUBLIC_HDRS} ${PLIBSYS_PRIVATE_HDRS})
+endif()
+
+# Add include directories
+if (COMMAND target_include_directories)
+ target_include_directories (plibsys PUBLIC ${PLIBSYS_INCLUDE_DIRS})
+
+ if (PLIBSYS_BUILD_STATIC)
+ target_include_directories (plibsysstatic PUBLIC ${PLIBSYS_INCLUDE_DIRS})
+ endif()
+else()
+ include_directories (${PLIBSYS_INCLUDE_DIRS})
+endif()
+
+# Add compile definitions
+if (COMMAND target_compile_definitions)
+ target_compile_definitions (plibsys PRIVATE ${PLIBSYS_COMPILE_DEFS})
+
+ if (PLIBSYS_BUILD_STATIC)
+ target_compile_definitions (plibsysstatic PRIVATE ${PLIBSYS_COMPILE_DEFS})
+ endif()
+else()
+ add_definitions (${PLIBSYS_COMPILE_DEFS})
+endif()
+
+set_target_properties (plibsys PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
+set_target_properties (plibsys PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIR})
+set_target_properties (plibsys PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIR})
+
+# OpenBSD uses a bit different library versioning
+if (PLIBSYS_TARGET_OS STREQUAL openbsd)
+ set (PLIBSYS_SOVERSION ${PLIBSYS_VERSION_MAJOR}.${PLIBSYS_VERSION_MINOR})
+endif()
+
+if (NOT PLIBSYS_TARGET_OS STREQUAL os2 AND NOT PLIBSYS_TARGET_OS STREQUAL amigaos)
+ set_target_properties (plibsys PROPERTIES SOVERSION ${PLIBSYS_SOVERSION})
+endif()
+
+if (PLIBSYS_BUILD_STATIC)
+ set_target_properties (plibsysstatic PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIR})
+
+ if (NOT PLIBSYS_TARGET_OS STREQUAL os2)
+ set_target_properties (plibsysstatic PROPERTIES SOVERSION ${PLIBSYS_SOVERSION})
+ endif()
+endif()
+
+if (PLIBSYS_PLATFORM_CFLAGS)
+ foreach (PLATFORM_CFLAG ${PLIBSYS_PLATFORM_CFLAGS})
+ set (PLIBSYS_PLATFORM_CFLAGS_STR "${PLIBSYS_PLATFORM_CFLAGS_STR} ${PLATFORM_CFLAG}")
+ endforeach()
+
+ set_target_properties (plibsys PROPERTIES COMPILE_FLAGS "${PLIBSYS_PLATFORM_CFLAGS_STR}")
+
+ if (PLIBSYS_BUILD_STATIC)
+ set_target_properties (plibsysstatic PROPERTIES COMPILE_FLAGS "${PLIBSYS_PLATFORM_CFLAGS_STR}")
+ endif()
+endif()
+
+if (PLIBSYS_PLATFORM_LDFLAGS)
+ foreach (PLATFORM_LDFLAG ${PLIBSYS_PLATFORM_LDFLAGS})
+ set (PLIBSYS_PLATFORM_LDFLAGS_STR "${PLIBSYS_PLATFORM_LDFLAGS_STR} ${PLATFORM_LDFLAG}")
+ endforeach()
+
+ set_target_properties (plibsys PROPERTIES LINK_FLAGS "${PLIBSYS_PLATFORM_LDFLAGS_STR}")
+
+ if (PLIBSYS_BUILD_STATIC)
+ set_target_properties (plibsysstatic PROPERTIES LINK_FLAGS "${PLIBSYS_PLATFORM_LDFLAGS_STR}")
+ endif()
+endif()
+
+target_link_libraries (plibsys ${PLIBSYS_PLATFORM_LINK_LIBRARIES})
+
+if (PLIBSYS_BUILD_STATIC)
+ target_link_libraries (plibsysstatic ${PLIBSYS_PLATFORM_LINK_LIBRARIES})
+endif()
+
+if (PLIBSYS_BUILD_STATIC)
+ set (PLIBSYS_INSTALL_TARGETS plibsys plibsysstatic)
+else()
+ set (PLIBSYS_INSTALL_TARGETS plibsys)
+endif()
+
+if (PLIBSYS_NATIVE_WINDOWS)
+ install (TARGETS ${PLIBSYS_INSTALL_TARGETS}
+ DESTINATION lib
+ RUNTIME DESTINATION lib
+ COMPONENT Core
+ )
+
+ if (NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE)
+ endif()
+
+ set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
+ include (InstallRequiredSystemLibraries)
+
+ install (PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
+ DESTINATION lib
+ COMPONENT Core
+ )
+endif()
+
+# Prepare installation dirs
+if (NOT CMAKE_INSTALL_LIBDIR)
+ set (CMAKE_INSTALL_LIBDIR "lib")
+endif()
+
+if (NOT CMAKE_INSTALL_INCLUDEDIR)
+ set (CMAKE_INSTALL_INCLUDEDIR "include")
+endif()
+
+install (TARGETS ${PLIBSYS_INSTALL_TARGETS} EXPORT plibsys-targets
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ COMPONENT Core
+)
+install (TARGETS ${PLIBSYS_INSTALL_TARGETS}
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ COMPONENT Core
+)
+install (FILES
+ ${PLIBSYS_PUBLIC_HDRS}
+ ${CMAKE_BINARY_DIR}/plibsysconfig.h
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/plibsys
+ COMPONENT Core
+)
+
+if (PLIBSYS_VA_COPY)
+ set(PLIBSYS_VA_COPY_STATUS "YES")
+else()
+ set(PLIBSYS_VA_COPY_STATUS "NO")
+endif()
+
+if (PLIBSYS_OS_BITS STREQUAL "universal")
+ set (PLIBSYS_ADDRESS_MODEL "universal")
+else()
+ set (PLIBSYS_ADDRESS_MODEL "${PLIBSYS_OS_BITS} bit")
+endif()
+
+# Print summary
+SET (PLIBSYS_SUMMARY
+"
+ == Build configuration ==
+
+ Platfrom: ${PLIBSYS_TARGET_OS}
+ Compiler: ${PLIBSYS_C_COMPILER}
+ Address model: ${PLIBSYS_ADDRESS_MODEL}
+
+ Thread model: ${PLIBSYS_THREAD_MODEL}
+ RW lock model: ${PLIBSYS_RWLOCK_MODEL}
+ IPC model: ${PLIBSYS_IPC_MODEL}
+ DIR model: ${PLIBSYS_DIR_MODEL}
+ Library loader model: ${PLIBSYS_LIBRARYLOADER_MODEL}
+ Time profiler model: ${PLIBSYS_TIME_PROFILER_MODEL}
+ Atomic model: ${PLIBSYS_ATOMIC_MODEL}
+
+ Platform defines: ${PLIBSYS_PLATFORM_DEFINES}
+ Platform CFLAGS: ${PLIBSYS_PLATFORM_CFLAGS}
+ Platform LDFLAGS: ${PLIBSYS_PLATFORM_LDFLAGS}
+ Platform libraries: ${PLIBSYS_PLATFORM_LINK_LIBRARIES}
+
+ Build static library: ${PLIBSYS_BUILD_STATIC}
+ Build tests: ${PLIBSYS_TESTS}
+ Coverage support: ${PLIBSYS_COVERAGE}
+ Visibility: ${PLIBSYS_VISIBILITY}
+
+ va_copy availability: ${PLIBSYS_VA_COPY_STATUS}
+
+")
+
+message ("${PLIBSYS_SUMMARY}")
diff --git a/3rdparty/plibsys/src/patomic-c11.c b/3rdparty/plibsys/src/patomic-c11.c
new file mode 100644
index 0000000..e6ed760
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic-c11.c
@@ -0,0 +1,182 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+
+#ifdef P_CC_SUN
+# define PATOMIC_INT_CAST(x) (pint *) (x)
+# define PATOMIC_SIZE_CAST(x) (psize *) (x)
+#else
+# define PATOMIC_INT_CAST(x) x
+# define PATOMIC_SIZE_CAST(x) x
+#endif
+
+P_LIB_API pint
+p_atomic_int_get (const volatile pint *atomic)
+{
+ return (pint) __atomic_load_4 (PATOMIC_INT_CAST (atomic), __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API void
+p_atomic_int_set (volatile pint *atomic,
+ pint val)
+{
+ __atomic_store_4 (PATOMIC_INT_CAST (atomic), val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API void
+p_atomic_int_inc (volatile pint *atomic)
+{
+ (void) __atomic_fetch_add (atomic, 1, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API pboolean
+p_atomic_int_dec_and_test (volatile pint *atomic)
+{
+ return (__atomic_fetch_sub (atomic, 1, __ATOMIC_SEQ_CST) == 1) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval)
+{
+ pint tmp_int = oldval;
+
+ return (pboolean) __atomic_compare_exchange_n (PATOMIC_INT_CAST (atomic),
+ &tmp_int,
+ newval,
+ 0,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API pint
+p_atomic_int_add (volatile pint *atomic,
+ pint val)
+{
+ return (pint) __atomic_fetch_add (atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API puint
+p_atomic_int_and (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __atomic_fetch_and (atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API puint
+p_atomic_int_or (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __atomic_fetch_or (atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API puint
+p_atomic_int_xor (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __atomic_fetch_xor (atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API ppointer
+p_atomic_pointer_get (const volatile void *atomic)
+{
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ return (ppointer) __atomic_load_8 (PATOMIC_SIZE_CAST ((const volatile psize *) atomic), __ATOMIC_SEQ_CST);
+#else
+ return (ppointer) __atomic_load_4 (PATOMIC_SIZE_CAST ((const volatile psize *) atomic), __ATOMIC_SEQ_CST);
+#endif
+}
+
+P_LIB_API void
+p_atomic_pointer_set (volatile void *atomic,
+ ppointer val)
+{
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ __atomic_store_8 (PATOMIC_SIZE_CAST ((volatile psize *) atomic), (psize) val, __ATOMIC_SEQ_CST);
+#else
+ __atomic_store_4 (PATOMIC_SIZE_CAST ((volatile psize *) atomic), (psize) val, __ATOMIC_SEQ_CST);
+#endif
+}
+
+P_LIB_API pboolean
+p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval)
+{
+ ppointer tmp_pointer = oldval;
+
+ return (pboolean) __atomic_compare_exchange_n (PATOMIC_SIZE_CAST ((volatile psize *) atomic),
+ (psize *) &tmp_pointer,
+ PPOINTER_TO_PSIZE (newval),
+ 0,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API pssize
+p_atomic_pointer_add (volatile void *atomic,
+ pssize val)
+{
+ return (pssize) __atomic_fetch_add ((volatile pssize *) atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API psize
+p_atomic_pointer_and (volatile void *atomic,
+ psize val)
+{
+ return (psize) __atomic_fetch_and ((volatile psize *) atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API psize
+p_atomic_pointer_or (volatile void *atomic,
+ psize val)
+{
+ return (psize) __atomic_fetch_or ((volatile pssize *) atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API psize
+p_atomic_pointer_xor (volatile void *atomic,
+ psize val)
+{
+ return (psize) __atomic_fetch_xor ((volatile pssize *) atomic, val, __ATOMIC_SEQ_CST);
+}
+
+P_LIB_API pboolean
+p_atomic_is_lock_free (void)
+{
+ return TRUE;
+}
+
+void
+p_atomic_thread_init (void)
+{
+}
+
+void
+p_atomic_thread_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/patomic-decc.c b/3rdparty/plibsys/src/patomic-decc.c
new file mode 100644
index 0000000..d103aa9
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic-decc.c
@@ -0,0 +1,286 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+
+#ifdef P_OS_VMS
+# include <builtins.h>
+#else
+# include <machine/builtins.h>
+#endif
+
+#ifdef __ia64
+# define PATOMIC_DECC_CAS_LONG(atomic_src, oldval, newval, atomic_dst) \
+ __CMP_SWAP_LONG ((volatile void *) (atomic_src), \
+ (pint) (oldval), \
+ (pint) (newval))
+# define PATOMIC_DECC_CAS_QUAD(atomic_src, oldval, newval, atomic_dst) \
+ __CMP_SWAP_QUAD ((volatile void *) (atomic_src), \
+ (pint64) (oldval), \
+ (pint64) (newval))
+#else
+# define PATOMIC_DECC_CAS_LONG(atomic_src, oldval, newval, atomic_dst) \
+ __CMP_STORE_LONG ((volatile void *) (atomic_src), \
+ (pint) (oldval), \
+ (pint) (newval), \
+ (volatile void *) (atomic_dst))
+# define PATOMIC_DECC_CAS_QUAD(atomic_src, oldval, newval, atomic_dst) \
+ __CMP_STORE_QUAD ((volatile void *) (atomic_src), \
+ (pint64) (oldval), \
+ (pint64) (newval), \
+ (volatile void *) (atomic_dst))
+#endif
+
+P_LIB_API pint
+p_atomic_int_get (const volatile pint *atomic)
+{
+ __MB ();
+ return (pint) *atomic;
+}
+
+P_LIB_API void
+p_atomic_int_set (volatile pint *atomic,
+ pint val)
+{
+ (void) __ATOMIC_EXCH_LONG ((volatile void *) atomic, val);
+ __MB ();
+}
+
+P_LIB_API void
+p_atomic_int_inc (volatile pint *atomic)
+{
+ __MB ();
+ (void) __ATOMIC_INCREMENT_LONG ((volatile void *) atomic);
+ __MB ();
+}
+
+P_LIB_API pboolean
+p_atomic_int_dec_and_test (volatile pint *atomic)
+{
+ pboolean result;
+
+ __MB ();
+ result = __ATOMIC_DECREMENT_LONG ((volatile void *) atomic) == 1 ? TRUE : FALSE;
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API pboolean
+p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval)
+{
+ pboolean result;
+
+ __MB ();
+ result = PATOMIC_DECC_CAS_LONG (atomic, oldval, newval, atomic) == 1 ? TRUE : FALSE;
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API pint
+p_atomic_int_add (volatile pint *atomic,
+ pint val)
+{
+ pint result;
+
+ __MB ();
+ result = __ATOMIC_ADD_LONG ((volatile void *) atomic, val);
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API puint
+p_atomic_int_and (volatile puint *atomic,
+ puint val)
+{
+ puint result;
+
+ __MB ();
+ result = (puint) __ATOMIC_AND_LONG ((volatile void *) atomic, (pint) val);
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API puint
+p_atomic_int_or (volatile puint *atomic,
+ puint val)
+{
+ puint result;
+
+ __MB ();
+ result = (puint) __ATOMIC_OR_LONG ((volatile void *) atomic, (pint) val);
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API puint
+p_atomic_int_xor (volatile puint *atomic,
+ puint val)
+{
+ pint i;
+
+ do {
+ __MB ();
+ i = (pint) (*atomic);
+ } while (PATOMIC_DECC_CAS_LONG (atomic, i, i ^ ((pint) val), atomic) != 1);
+
+ __MB ();
+
+ return i;
+}
+
+P_LIB_API ppointer
+p_atomic_pointer_get (const volatile void *atomic)
+{
+ __MB ();
+ return (ppointer) (* ((const volatile psize *) atomic));
+}
+
+P_LIB_API void
+p_atomic_pointer_set (volatile void *atomic,
+ ppointer val)
+{
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ (void) __ATOMIC_EXCH_QUAD (atomic, (pint64) val);
+#else
+ (void) __ATOMIC_EXCH_LONG (atomic, (pint) val);
+#endif
+ __MB ();
+}
+
+P_LIB_API pboolean
+p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval)
+{
+ pboolean result;
+
+ __MB ();
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ result = PATOMIC_DECC_CAS_QUAD (atomic, oldval, newval, atomic) == 1 ? TRUE : FALSE;
+#else
+ result = PATOMIC_DECC_CAS_LONG (atomic, oldval, newval, atomic) == 1 ? TRUE : FALSE;
+#endif
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API pssize
+p_atomic_pointer_add (volatile void *atomic,
+ pssize val)
+{
+ pssize result;
+
+ __MB ();
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ result = (pssize) __ATOMIC_ADD_QUAD (atomic, (pint64) val);
+#else
+ result = (pssize) __ATOMIC_ADD_LONG (atomic, (pint) val);
+#endif
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API psize
+p_atomic_pointer_and (volatile void *atomic,
+ psize val)
+{
+ psize result;
+
+ __MB ();
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ result = (psize) __ATOMIC_AND_QUAD (atomic, (pint64) val);
+#else
+ result = (psize) __ATOMIC_AND_LONG (atomic, (pint) val);
+#endif
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API psize
+p_atomic_pointer_or (volatile void *atomic,
+ psize val)
+{
+ psize result;
+
+ __MB ();
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ result = (psize) __ATOMIC_OR_QUAD (atomic, (pint64) val);
+#else
+ result = (psize) __ATOMIC_OR_LONG (atomic, (pint) val);
+#endif
+ __MB ();
+
+ return result;
+}
+
+P_LIB_API psize
+p_atomic_pointer_xor (volatile void *atomic,
+ psize val)
+{
+#if (PLIBSYS_SIZEOF_VOID_P == 8)
+ pint64 i;
+
+ do {
+ __MB ();
+ i = (pint64) (* ((volatile psize *) atomic));
+ } while (PATOMIC_DECC_CAS_QUAD (atomic, i, i ^ ((pint64) val), atomic) != 1);
+#else
+ pint i;
+
+ do {
+ __MB ();
+ i = (pint) (* ((volatile psize *) atomic));
+ } while (PATOMIC_DECC_CAS_LONG (atomic, i, i ^ ((pint) val), atomic) != 1);
+#endif
+ __MB ();
+
+ return (psize) i;
+}
+
+P_LIB_API pboolean
+p_atomic_is_lock_free (void)
+{
+ return TRUE;
+}
+
+void
+p_atomic_thread_init (void)
+{
+}
+
+void
+p_atomic_thread_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/patomic-sim.c b/3rdparty/plibsys/src/patomic-sim.c
new file mode 100644
index 0000000..12d0604
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic-sim.c
@@ -0,0 +1,268 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+#include "pmutex.h"
+
+/* We have to use the slow, but safe locking method. */
+static PMutex *pp_atomic_mutex = NULL;
+
+P_LIB_API pint
+p_atomic_int_get (const volatile pint *atomic)
+{
+ pint value;
+
+ p_mutex_lock (pp_atomic_mutex);
+ value = *atomic;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return value;
+}
+
+P_LIB_API void
+p_atomic_int_set (volatile pint *atomic,
+ pint val)
+{
+ p_mutex_lock (pp_atomic_mutex);
+ *atomic = val;
+ p_mutex_unlock (pp_atomic_mutex);
+}
+
+P_LIB_API void
+p_atomic_int_inc (volatile pint *atomic)
+{
+ p_mutex_lock (pp_atomic_mutex);
+ (*atomic)++;
+ p_mutex_unlock (pp_atomic_mutex);
+}
+
+P_LIB_API pboolean
+p_atomic_int_dec_and_test (volatile pint *atomic)
+{
+ pboolean is_zero;
+
+ p_mutex_lock (pp_atomic_mutex);
+ is_zero = --(*atomic) == 0;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return is_zero;
+}
+
+P_LIB_API pboolean
+p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval)
+{
+ pboolean success;
+
+ p_mutex_lock (pp_atomic_mutex);
+
+ if ((success = (*atomic == oldval)))
+ *atomic = newval;
+
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return success;
+}
+
+P_LIB_API pint
+p_atomic_int_add (volatile pint *atomic,
+ pint val)
+{
+ pint oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *atomic;
+ *atomic = oldval + val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API puint
+p_atomic_int_and (volatile puint *atomic,
+ puint val)
+{
+ puint oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *atomic;
+ *atomic = oldval & val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API puint
+p_atomic_int_or (volatile puint *atomic,
+ puint val)
+{
+ puint oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *atomic;
+ *atomic = oldval | val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API puint
+p_atomic_int_xor (volatile puint *atomic,
+ puint val)
+{
+ puint oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *atomic;
+ *atomic = oldval ^ val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API ppointer
+p_atomic_pointer_get (const volatile void *atomic)
+{
+ const volatile ppointer *ptr = atomic;
+ ppointer value;
+
+ p_mutex_lock (pp_atomic_mutex);
+ value = *ptr;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return value;
+}
+
+P_LIB_API void
+p_atomic_pointer_set (volatile void *atomic,
+ ppointer val)
+{
+ volatile ppointer *ptr = atomic;
+
+ p_mutex_lock (pp_atomic_mutex);
+ *ptr = val;
+ p_mutex_unlock (pp_atomic_mutex);
+}
+
+P_LIB_API pboolean
+p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval)
+{
+ volatile ppointer *ptr = atomic;
+ pboolean success;
+
+ p_mutex_lock (pp_atomic_mutex);
+
+ if ((success = (*ptr == oldval)))
+ *ptr = newval;
+
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return success;
+}
+
+P_LIB_API pssize
+p_atomic_pointer_add (volatile void *atomic,
+ pssize val)
+{
+ volatile pssize *ptr = atomic;
+ pssize oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *ptr;
+ *ptr = oldval + val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API psize
+p_atomic_pointer_and (volatile void *atomic,
+ psize val)
+{
+ volatile psize *ptr = atomic;
+ psize oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *ptr;
+ *ptr = oldval & val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API psize
+p_atomic_pointer_or (volatile void *atomic,
+ psize val)
+{
+ volatile psize *ptr = atomic;
+ psize oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *ptr;
+ *ptr = oldval | val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API psize
+p_atomic_pointer_xor (volatile void *atomic,
+ psize val)
+{
+ volatile psize *ptr = atomic;
+ psize oldval;
+
+ p_mutex_lock (pp_atomic_mutex);
+ oldval = *ptr;
+ *ptr = oldval ^ val;
+ p_mutex_unlock (pp_atomic_mutex);
+
+ return oldval;
+}
+
+P_LIB_API pboolean
+p_atomic_is_lock_free (void)
+{
+ return FALSE;
+}
+
+void
+p_atomic_thread_init (void)
+{
+ if (P_LIKELY (pp_atomic_mutex == NULL))
+ pp_atomic_mutex = p_mutex_new ();
+}
+
+void
+p_atomic_thread_shutdown (void)
+{
+ if (P_LIKELY (pp_atomic_mutex != NULL)) {
+ p_mutex_free (pp_atomic_mutex);
+ pp_atomic_mutex = NULL;
+ }
+}
diff --git a/3rdparty/plibsys/src/patomic-sync.c b/3rdparty/plibsys/src/patomic-sync.c
new file mode 100644
index 0000000..04a8d81
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic-sync.c
@@ -0,0 +1,190 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+
+#ifdef P_CC_CRAY
+# include <intrinsics.h>
+#endif
+
+P_LIB_API pint
+p_atomic_int_get (const volatile pint *atomic)
+{
+#ifdef P_CC_CRAY
+ __builtin_ia32_mfence ();
+#else
+ __sync_synchronize ();
+#endif
+ return *atomic;
+}
+
+P_LIB_API void
+p_atomic_int_set (volatile pint *atomic,
+ pint val)
+{
+ *atomic = val;
+#ifdef P_CC_CRAY
+ __builtin_ia32_mfence ();
+#else
+ __sync_synchronize ();
+#endif
+}
+
+P_LIB_API void
+p_atomic_int_inc (volatile pint *atomic)
+{
+ (void) __sync_fetch_and_add (atomic, 1);
+}
+
+P_LIB_API pboolean
+p_atomic_int_dec_and_test (volatile pint *atomic)
+{
+ return __sync_fetch_and_sub (atomic, 1) == 1 ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval)
+{
+#ifdef P_CC_CRAY
+ return __sync_val_compare_and_swap (atomic, oldval, newval) == oldval ? TRUE : FALSE;
+#else
+ return (pboolean) __sync_bool_compare_and_swap (atomic, oldval, newval);
+#endif
+}
+
+P_LIB_API pint
+p_atomic_int_add (volatile pint *atomic,
+ pint val)
+{
+ return (pint) __sync_fetch_and_add (atomic, val);
+}
+
+P_LIB_API puint
+p_atomic_int_and (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __sync_fetch_and_and (atomic, val);
+}
+
+P_LIB_API puint
+p_atomic_int_or (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __sync_fetch_and_or (atomic, val);
+}
+
+P_LIB_API puint
+p_atomic_int_xor (volatile puint *atomic,
+ puint val)
+{
+ return (puint) __sync_fetch_and_xor (atomic, val);
+}
+
+P_LIB_API ppointer
+p_atomic_pointer_get (const volatile void *atomic)
+{
+#ifdef P_CC_CRAY
+ __builtin_ia32_mfence ();
+#else
+ __sync_synchronize ();
+#endif
+ return (ppointer) *((const volatile psize *) atomic);
+}
+
+P_LIB_API void
+p_atomic_pointer_set (volatile void *atomic,
+ ppointer val)
+{
+ volatile psize *cur_val = (volatile psize *) atomic;
+
+ *cur_val = (psize) val;
+#ifdef P_CC_CRAY
+ __builtin_ia32_mfence ();
+#else
+ __sync_synchronize ();
+#endif
+}
+
+P_LIB_API pboolean
+p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval)
+{
+#ifdef P_CC_CRAY
+ return __sync_val_compare_and_swap ((volatile psize *) atomic,
+ (psize) oldval,
+ (psize) newval) == ((psize) oldval) ? TRUE : FALSE;
+#else
+ return (pboolean) __sync_bool_compare_and_swap ((volatile psize *) atomic,
+ (psize) oldval,
+ (psize) newval);
+#endif
+}
+
+P_LIB_API pssize
+p_atomic_pointer_add (volatile void *atomic,
+ pssize val)
+{
+ return (pssize) __sync_fetch_and_add ((volatile pssize *) atomic, val);
+}
+
+P_LIB_API psize
+p_atomic_pointer_and (volatile void *atomic,
+ psize val)
+{
+ return (psize) __sync_fetch_and_and ((volatile psize *) atomic, val);
+}
+
+P_LIB_API psize
+p_atomic_pointer_or (volatile void *atomic,
+ psize val)
+{
+ return (psize) __sync_fetch_and_or ((volatile psize *) atomic, val);
+}
+
+P_LIB_API psize
+p_atomic_pointer_xor (volatile void *atomic,
+ psize val)
+{
+ return (psize) __sync_fetch_and_xor ((volatile psize *) atomic, val);
+}
+
+P_LIB_API pboolean
+p_atomic_is_lock_free (void)
+{
+ return TRUE;
+}
+
+void
+p_atomic_thread_init (void)
+{
+}
+
+void
+p_atomic_thread_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/patomic-win.c b/3rdparty/plibsys/src/patomic-win.c
new file mode 100644
index 0000000..597151d
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic-win.c
@@ -0,0 +1,272 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+
+/* Prepare MemoryBarrier() */
+#if defined (P_CC_WATCOM) || defined (P_CC_BORLAND)
+# if defined (_M_X64) || defined (_M_AMD64)
+# define MemoryBarrier __faststorefence
+# elseif defined (_M_IA64)
+# define MemoryBarrier __mf
+# else
+# ifdef P_CC_WATCOM
+inline
+# else
+FORCEINLINE
+# endif /* P_CC_WATCOM */
+VOID MemoryBarrier (VOID)
+{
+ LONG Barrier = 0;
+ (void) (Barrier);
+ __asm {
+ xchg Barrier, eax
+ }
+}
+# endif /* _M_X64 || _M_AMD64 */
+#endif /* P_CC_WATCOM || P_CC_BORLAND */
+
+#if !defined (P_OS_WIN64) && (defined (P_CC_MSVC) && _MSC_VER > 1200)
+ /* Tell compiler about intrinsics to suppress warnings,
+ * see: https://msdn.microsoft.com/en-us/library/hh977023.aspx */
+# include <intrin.h>
+# define InterlockedAnd _InterlockedAnd
+# define InterlockedOr _InterlockedOr
+# define InterlockedXor _InterlockedXor
+# pragma intrinsic(_InterlockedAnd)
+# pragma intrinsic(_InterlockedOr)
+# pragma intrinsic(_InterlockedXor)
+#endif
+
+#if (defined (P_CC_MSVC) && _MSC_VER <= 1200) || defined (P_CC_WATCOM) \
+ || defined (P_CC_BORLAND)
+/* Inlined versions for older compilers */
+static LONG
+ppInterlockedAnd (LONG volatile *atomic,
+ LONG val)
+{
+ LONG i, j;
+
+ j = *atomic;
+ do {
+ i = j;
+ j = InterlockedCompareExchange (atomic, i & val, i);
+ } while (i != j);
+
+ return j;
+}
+
+# define InterlockedAnd(a,b) ppInterlockedAnd(a,b)
+
+static LONG
+ppInterlockedOr (LONG volatile *atomic,
+ LONG val)
+{
+ LONG i, j;
+
+ j = *atomic;
+ do {
+ i = j;
+ j = InterlockedCompareExchange (atomic, i | val, i);
+ } while (i != j);
+
+ return j;
+}
+
+# define InterlockedOr(a,b) ppInterlockedOr(a,b)
+
+static LONG
+ppInterlockedXor (LONG volatile *atomic,
+ LONG val)
+{
+ LONG i, j;
+
+ j = *atomic;
+ do {
+ i = j;
+ j = InterlockedCompareExchange (atomic, i ^ val, i);
+ } while (i != j);
+
+ return j;
+}
+
+# define InterlockedXor(a,b) ppInterlockedXor(a,b)
+#endif
+
+/* http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx */
+
+P_LIB_API pint
+p_atomic_int_get (const volatile pint *atomic)
+{
+ MemoryBarrier ();
+ return *atomic;
+}
+
+P_LIB_API void
+p_atomic_int_set (volatile pint *atomic,
+ pint val)
+{
+ *atomic = val;
+ MemoryBarrier ();
+}
+
+P_LIB_API void
+p_atomic_int_inc (volatile pint *atomic)
+{
+ InterlockedIncrement ((LONG volatile *) atomic);
+}
+
+P_LIB_API pboolean
+p_atomic_int_dec_and_test (volatile pint *atomic)
+{
+ return InterlockedDecrement ((LONG volatile *) atomic) == 0 ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval)
+{
+ return InterlockedCompareExchange ((LONG volatile *) atomic,
+ (LONG) newval,
+ (LONG) oldval) == oldval;
+}
+
+P_LIB_API pint
+p_atomic_int_add (volatile pint *atomic,
+ pint val)
+{
+ return (pint) InterlockedExchangeAdd ((LONG volatile *) atomic, (LONG) val);
+}
+
+P_LIB_API puint
+p_atomic_int_and (volatile puint *atomic,
+ puint val)
+{
+ return (puint) InterlockedAnd ((LONG volatile *) atomic, (LONG) val);
+}
+
+P_LIB_API puint
+p_atomic_int_or (volatile puint *atomic,
+ puint val)
+{
+ return (puint) InterlockedOr ((LONG volatile *) atomic, (LONG) val);
+}
+
+P_LIB_API puint
+p_atomic_int_xor (volatile puint *atomic,
+ puint val)
+{
+ return (puint) InterlockedXor ((LONG volatile *) atomic, (LONG) val);
+}
+
+P_LIB_API ppointer
+p_atomic_pointer_get (const volatile void *atomic)
+{
+ const volatile ppointer *ptr = (const volatile ppointer *) atomic;
+
+ MemoryBarrier ();
+ return *ptr;
+}
+
+P_LIB_API void
+p_atomic_pointer_set (volatile void *atomic,
+ ppointer val)
+{
+ volatile ppointer *ptr = (volatile ppointer *) atomic;
+
+ *ptr = val;
+ MemoryBarrier ();
+}
+
+P_LIB_API pboolean
+p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval)
+{
+ return InterlockedCompareExchangePointer ((volatile PVOID *) atomic,
+ (PVOID) newval,
+ (PVOID) oldval) == oldval ? TRUE : FALSE;
+}
+
+P_LIB_API pssize
+p_atomic_pointer_add (volatile void *atomic,
+ pssize val)
+{
+#if PLIBSYS_SIZEOF_VOID_P == 8
+ return (pssize) InterlockedExchangeAdd64 ((LONGLONG volatile *) atomic, (LONGLONG) val);
+#else
+ return (pssize) InterlockedExchangeAdd ((LONG volatile *) atomic, (LONG) val);
+#endif
+}
+
+P_LIB_API psize
+p_atomic_pointer_and (volatile void *atomic,
+ psize val)
+{
+#if PLIBSYS_SIZEOF_VOID_P == 8
+ return (psize) InterlockedAnd64 ((LONGLONG volatile *) atomic, (LONGLONG) val);
+#else
+ return (psize) InterlockedAnd ((LONG volatile *) atomic, (LONG) val);
+#endif
+}
+
+P_LIB_API psize
+p_atomic_pointer_or (volatile void *atomic,
+ psize val)
+{
+#if PLIBSYS_SIZEOF_VOID_P == 8
+ return (psize) InterlockedOr64 ((LONGLONG volatile *) atomic, (LONGLONG) val);
+#else
+ return (psize) InterlockedOr ((LONG volatile *) atomic, (LONG) val);
+#endif
+}
+
+P_LIB_API psize
+p_atomic_pointer_xor (volatile void *atomic,
+ psize val)
+{
+#if PLIBSYS_SIZEOF_VOID_P == 8
+ return (psize) InterlockedXor64 ((LONGLONG volatile *) atomic, (LONGLONG) val);
+#else
+ return (psize) InterlockedXor ((LONG volatile *) atomic, (LONG) val);
+#endif
+}
+
+P_LIB_API pboolean
+p_atomic_is_lock_free (void)
+{
+ return TRUE;
+}
+
+void
+p_atomic_thread_init (void)
+{
+}
+
+void
+p_atomic_thread_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/patomic.h b/3rdparty/plibsys/src/patomic.h
new file mode 100644
index 0000000..fc451fe
--- /dev/null
+++ b/3rdparty/plibsys/src/patomic.h
@@ -0,0 +1,310 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file patomic.h
+ * @brief Atomic operations
+ * @author Alexander Saprykin
+ *
+ * Atomic operations can be used to avoid heavy thread synchronization
+ * primitives such as mutexes, semaphores and so on. These operations are
+ * performed atomically and can't be preempted by another thread.
+ *
+ * Lock-free atomic operations require software and hardware support. Usually
+ * lock-free atomic operations are implemented with low-level using assembly
+ * inlines. Some of the compilers provide built-in routines to perform atomic
+ * operations. You can use the p_atomic_is_lock_free() call to check whether
+ * such a support is provided or not.
+ *
+ * If there is no hardware or software support for lock-free atomic operations
+ * then they can be simulated (though in rather slower manner) using a thread
+ * global synchronization primitive (i.e. mutex), but it could block threads
+ * while performing atomic operations on distinct variables from distinct
+ * threads.
+ *
+ * The Windows platform provides all the required lock-free operations in most
+ * cases, so it always has lock-free support.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PATOMIC_H
+#define PLIBSYS_HEADER_PATOMIC_H
+
+#include <ptypes.h>
+#include <pmacros.h>
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Gets #pint value from @a atomic.
+ * @param atomic Pointer to #pint to get the value from.
+ * @return Integer value.
+ * @since 0.0.1
+ *
+ * This call acts as a full compiler and hardware memory barrier (before the
+ * get).
+ */
+P_LIB_API pint p_atomic_int_get (const volatile pint *atomic);
+
+/**
+ * @brief Sets #pint value to @a atomic.
+ * @param[out] atomic Pointer to #pint to set the value for.
+ * @param val New #pint value.
+ * @since 0.0.1
+ *
+ * This call acts as a full compiler and hardware memory barrier (after the
+ * set).
+ */
+P_LIB_API void p_atomic_int_set (volatile pint *atomic,
+ pint val);
+
+/**
+ * @brief Increments #pint value from @a atomic by 1.
+ * @param[in,out] atomic Pointer to #pint to increment the value.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of `{ *atomic += 1; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API void p_atomic_int_inc (volatile pint *atomic);
+
+/**
+ * @brief Decrements #pint value from @a atomic by 1 and tests the result for
+ * zero.
+ * @param[in,out] atomic Pointer to #pint to decrement the value.
+ * @return TRUE if the new value is equal to zero, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ *atomic -= 1; return (*atomic == 0); }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API pboolean p_atomic_int_dec_and_test (volatile pint *atomic);
+
+/**
+ * @brief Compares @a oldval with the value pointed to by @a atomic and if
+ * they are equal, atomically exchanges the value of @a atomic with @a newval.
+ * @param[in,out] atomic Pointer to #pint.
+ * @param oldval Old #pint value.
+ * @param newval New #pint value.
+ * @return TRUE if @a atomic value was equal @a oldval, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * This compare and exchange is done atomically.
+ *
+ * Think of this operation as an atomic version of
+ * `{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API pboolean p_atomic_int_compare_and_exchange (volatile pint *atomic,
+ pint oldval,
+ pint newval);
+
+/**
+ * @brief Atomically adds #pint value to @a atomic value.
+ * @param[in,out] atomic Pointer to #pint.
+ * @param val Integer to add to @a atomic value.
+ * @return Old value before the addition.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic += val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API pint p_atomic_int_add (volatile pint *atomic,
+ pint val);
+
+/**
+ * @brief Atomically performs the bitwise 'and' operation of @a atomic value
+ * and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #puint.
+ * @param val #puint to perform bitwise 'and' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic &= val; return tmp; }`.
+ */
+P_LIB_API puint p_atomic_int_and (volatile puint *atomic,
+ puint val);
+
+/**
+ * @brief Atomically performs the bitwise 'or' operation of @a atomic value
+ * and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #puint.
+ * @param val #puint to perform bitwise 'or' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic |= val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API puint p_atomic_int_or (volatile puint *atomic,
+ puint val);
+
+/**
+ * @brief Atomically performs the bitwise 'xor' operation of @a atomic value
+ * and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #puint.
+ * @param val #puint to perform bitwise 'xor' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic ^= val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API puint p_atomic_int_xor (volatile puint *atomic,
+ puint val);
+
+/**
+ * @brief Gets #ppointer-sized value from @a atomic.
+ * @param atomic Pointer to get the value from.
+ * @return Value from the pointer.
+ * @since 0.0.1
+ *
+ * This call acts as a full compiler and hardware memory barrier (before the get).
+ */
+P_LIB_API ppointer p_atomic_pointer_get (const volatile void *atomic);
+
+/**
+ * @brief Sets @a val to #ppointer-sized @a atomic.
+ * @param[out] atomic Pointer to set the value for.
+ * @param val New value for @a atomic.
+ * @since 0.0.1
+ *
+ * This call acts as a full compiler and hardware memory barrier (after the set).
+ */
+P_LIB_API void p_atomic_pointer_set (volatile void *atomic,
+ ppointer val);
+
+/**
+ * @brief Compares @a oldval with the value pointed to by @a atomic and if
+ * they are equal, atomically exchanges the value of @a atomic with @a newval.
+ * @param[in,out] atomic Pointer to #ppointer-sized value.
+ * @param oldval Old #ppointer-sized value.
+ * @param newval New #ppointer-sized value.
+ * @return TRUE if @a atomic value was equal @a oldval, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * This compare and exchange is done atomically.
+ *
+ * Think of this operation as an atomic version of
+ * `{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API pboolean p_atomic_pointer_compare_and_exchange (volatile void *atomic,
+ ppointer oldval,
+ ppointer newval);
+
+/**
+ * @brief Atomically adds #ppointer-sized value to @a atomic value.
+ * @param[in,out] atomic Pointer to #ppointer-sized value.
+ * @param val Value to add to @a atomic value.
+ * @return Old value before the addition.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic += val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API pssize p_atomic_pointer_add (volatile void *atomic,
+ pssize val);
+
+/**
+ * @brief Atomically performs the bitwise 'and' operation of #ppointer-sized
+ * @a atomic value and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #ppointer-size value.
+ * @param val #psize to perform bitwise 'and' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic &= val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API psize p_atomic_pointer_and (volatile void *atomic,
+ psize val);
+
+/**
+ * @brief Atomically performs the bitwise 'or' operation of #ppointer-sized
+ * @a atomic value and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #ppointer-size value.
+ * @param val #psize to perform bitwise 'or' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic |= val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API psize p_atomic_pointer_or (volatile void *atomic,
+ psize val);
+
+/**
+ * @brief Atomically performs the bitwise 'xor' operation of #ppointer-sized
+ * @a atomic value and @a val storing the result back in @a atomic.
+ * @param[in,out] atomic Pointer to #ppointer-size value.
+ * @param val #psize to perform bitwise 'xor' with @a atomic value.
+ * @return Old @a atomic value before the operation.
+ * @since 0.0.1
+ *
+ * Think of this operation as an atomic version of
+ * `{ tmp = *atomic; *atomic ^= val; return tmp; }`.
+ *
+ * This call acts as a full compiler and hardware memory barrier.
+ */
+P_LIB_API psize p_atomic_pointer_xor (volatile void *atomic,
+ psize val);
+
+/**
+ * @brief Checks whether atomic operations are lock-free.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * Some underlying atomic model implementations may not support lock-free
+ * operations depending on hardware or software.
+ */
+P_LIB_API pboolean p_atomic_is_lock_free (void);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PATOMIC_H */
diff --git a/3rdparty/plibsys/src/pcondvariable-amiga.c b/3rdparty/plibsys/src/pcondvariable-amiga.c
new file mode 100644
index 0000000..1c91522
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-amiga.c
@@ -0,0 +1,230 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pcondvariable.h"
+#include "patomic.h"
+#include "pmem.h"
+#include "pspinlock.h"
+
+#include <stdlib.h>
+
+#include <proto/exec.h>
+
+typedef struct _PCondThread {
+ struct Task *thread;
+ struct _PCondThread *next;
+ ULONG sigmask;
+} PCondThread;
+
+struct PCondVariable_ {
+ PSpinLock *lock;
+ PCondThread *wait_head;
+ pint wait_count;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if ((ret->lock = p_spinlock_new ()) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if ((cond->wait_count > 0) || (cond->wait_head != NULL))
+ P_WARNING ("PCondVariable::p_cond_variable_free: destroying while threads are waiting");
+
+ p_spinlock_free (cond->lock);
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ PCondThread *wait_thread;
+ BYTE signal;
+ ULONG wait_singnals;
+
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ if ((wait_thread = p_malloc0 (sizeof (PCondThread))) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to allocate memory");
+ return FALSE;
+ }
+
+ wait_thread->thread = IExec->FindTask (NULL);
+ wait_thread->next = NULL;
+
+ signal = IExec->AllocSignal (-1);
+
+ if (signal == -1) {
+ P_WARNING ("PCondVariable::p_cond_variable_wait: no free signal slot left");
+ return FALSE;
+ }
+
+ wait_thread->sigmask = 1 << signal;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head != NULL)
+ cond->wait_head->next = wait_thread;
+ else
+ cond->wait_head = wait_thread;
+
+ p_atomic_int_inc ((volatile pint *) &cond->wait_count);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ if (p_mutex_unlock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock mutex");
+ return FALSE;
+ }
+
+ wait_singnals = IExec->Wait (wait_thread->sigmask);
+
+ if (p_mutex_lock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock mutex");
+ return FALSE;
+ }
+
+ IExec->FreeSignal (signal);
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ PCondThread *wait_thread;
+
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ wait_thread = cond->wait_head;
+ cond->wait_head = wait_thread->next;
+
+ p_atomic_int_add ((volatile pint *) &cond->wait_count, -1);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ IExec->Signal (wait_thread->thread, wait_thread->sigmask);
+
+ p_free (wait_thread);
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ PCondThread *cur_thread;
+ PCondThread *next_thread;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ cur_thread = cond->wait_head;
+
+ do {
+ IExec->Signal (cur_thread->thread, cur_thread->sigmask);
+
+ next_thread = cur_thread->next;
+ p_free (cur_thread);
+
+ cur_thread = next_thread;
+ } while (cur_thread != NULL);
+
+ cond->wait_head = NULL;
+ cond->wait_count = 0;
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-atheos.c b/3rdparty/plibsys/src/pcondvariable-atheos.c
new file mode 100644
index 0000000..f68e98b
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-atheos.c
@@ -0,0 +1,234 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pcondvariable.h"
+#include "pspinlock.h"
+#include "patomic.h"
+#include "pmem.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <atheos/semaphore.h>
+#include <atheos/threads.h>
+
+typedef struct _PCondThread {
+ thread_id thread;
+ struct _PCondThread *next;
+} PCondThread;
+
+struct PCondVariable_ {
+ PSpinLock *lock;
+ PCondThread *wait_head;
+ pint wait_count;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if ((ret->lock = p_spinlock_new ()) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if ((cond->wait_count > 0) || (cond->wait_head != NULL))
+ P_WARNING ("PCondVariable::p_cond_variable_free: destroying while threads are waiting");
+
+ p_spinlock_free (cond->lock);
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ PCondThread *wait_thread;
+
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ if ((wait_thread = p_malloc0 (sizeof (PCondThread))) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to allocate memory");
+ return FALSE;
+ }
+
+ wait_thread->thread = get_thread_id (NULL);
+ wait_thread->next = NULL;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head != NULL)
+ cond->wait_head->next = wait_thread;
+ else
+ cond->wait_head = wait_thread;
+
+ p_atomic_int_inc ((volatile pint *) &cond->wait_count);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ if (p_mutex_unlock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock mutex");
+ return FALSE;
+ }
+
+ suspend_thread (wait_thread->thread);
+
+ if (p_mutex_lock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock mutex");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ PCondThread *wait_thread;
+ thread_info thr_info;
+
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ wait_thread = cond->wait_head;
+ cond->wait_head = wait_thread->next;
+
+ p_atomic_int_add ((volatile pint *) &cond->wait_count, -1);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ while (get_thread_info (wait_thread->thread, &thr_info) == 0) {
+ if (thr_info.ti_state != TS_READY)
+ break;
+ }
+
+ resume_thread (wait_thread->thread);
+
+ p_free (wait_thread);
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ PCondThread *cur_thread;
+ PCondThread *next_thread;
+ thread_info thr_info;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ cur_thread = cond->wait_head;
+
+ do {
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ while (get_thread_info (cur_thread->thread, &thr_info) == 0) {
+ if (thr_info.ti_state != TS_READY)
+ break;
+ }
+
+ resume_thread (cur_thread->thread);
+
+ next_thread = cur_thread->next;
+ p_free (cur_thread);
+
+ cur_thread = next_thread;
+ } while (cur_thread != NULL);
+
+ cond->wait_head = NULL;
+ cond->wait_count = 0;
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-beos.c b/3rdparty/plibsys/src/pcondvariable-beos.c
new file mode 100644
index 0000000..78199d1
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-beos.c
@@ -0,0 +1,233 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pcondvariable.h"
+#include "pspinlock.h"
+#include "patomic.h"
+#include "pmem.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <kernel/OS.h>
+
+typedef struct _PCondThread {
+ thread_id thread;
+ struct _PCondThread *next;
+} PCondThread;
+
+struct PCondVariable_ {
+ PSpinLock *lock;
+ PCondThread *wait_head;
+ pint wait_count;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if ((ret->lock = p_spinlock_new ()) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if ((cond->wait_count > 0) || (cond->wait_head != NULL))
+ P_WARNING ("PCondVariable::p_cond_variable_free: destroying while threads are waiting");
+
+ p_spinlock_free (cond->lock);
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ PCondThread *wait_thread;
+
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ if ((wait_thread = p_malloc0 (sizeof (PCondThread))) == NULL) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to allocate memory");
+ return FALSE;
+ }
+
+ wait_thread->thread = find_thread (NULL);
+ wait_thread->next = NULL;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head != NULL)
+ cond->wait_head->next = wait_thread;
+ else
+ cond->wait_head = wait_thread;
+
+ p_atomic_int_inc ((volatile pint *) &cond->wait_count);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ if (p_mutex_unlock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to unlock mutex");
+ return FALSE;
+ }
+
+ suspend_thread (wait_thread->thread);
+
+ if (p_mutex_lock (mutex) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: failed to lock mutex");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ PCondThread *wait_thread;
+ thread_info thr_info;
+
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ wait_thread = cond->wait_head;
+ cond->wait_head = wait_thread->next;
+
+ p_atomic_int_add ((volatile pint *) &cond->wait_count, -1);
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ while (get_thread_info (wait_thread->thread, &thr_info) == B_OK) {
+ if (thr_info.state != B_THREAD_READY)
+ break;
+ }
+
+ resume_thread (wait_thread->thread);
+
+ p_free (wait_thread);
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ PCondThread *cur_thread;
+ PCondThread *next_thread;
+ thread_info thr_info;
+
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (p_spinlock_lock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast: failed to lock internal spinlock");
+ return FALSE;
+ }
+
+ if (cond->wait_head == NULL) {
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(1): failed to unlock internal spinlock");
+ return FALSE;
+ } else
+ return TRUE;
+ }
+
+ cur_thread = cond->wait_head;
+
+ do {
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ while (get_thread_info (cur_thread->thread, &thr_info) == B_OK) {
+ if (thr_info.state != B_THREAD_READY)
+ break;
+ }
+
+ resume_thread (cur_thread->thread);
+
+ next_thread = cur_thread->next;
+ p_free (cur_thread);
+
+ cur_thread = next_thread;
+ } while (cur_thread != NULL);
+
+ cond->wait_head = NULL;
+ cond->wait_count = 0;
+
+ if (p_spinlock_unlock (cond->lock) != TRUE) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast(2): failed to unlock internal spinlock");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-none.c b/3rdparty/plibsys/src/pcondvariable-none.c
new file mode 100644
index 0000000..b89baa3
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-none.c
@@ -0,0 +1,80 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pcondvariable.h"
+
+#include <stdlib.h>
+
+struct PCondVariable_ {
+ pint hdl;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ return NULL;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ P_UNUSED (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ P_UNUSED (cond);
+ P_UNUSED (mutex);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ P_UNUSED (cond);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ P_UNUSED (cond);
+
+ return FALSE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-os2.c b/3rdparty/plibsys/src/pcondvariable-os2.c
new file mode 100644
index 0000000..e3f0b0c
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-os2.c
@@ -0,0 +1,163 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+#include "pmem.h"
+#include "pcondvariable.h"
+
+#include <stdlib.h>
+
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSERRORS
+#include <os2.h>
+
+struct PCondVariable_ {
+ HEV waiters_sema;
+ pint waiters_count;
+ pint signaled;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (DosCreateEventSem (NULL,
+ (PHEV) &ret->waiters_sema,
+ 0,
+ FALSE) != NO_ERROR)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if (P_UNLIKELY (DosCloseEventSem (cond->waiters_sema) != NO_ERROR))
+ P_WARNING ("PCondVariable::p_cond_variable_free: DosCloseEventSem() failed");
+
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ APIRET ulrc;
+ APIRET reset_ulrc;
+
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ do {
+ p_atomic_int_inc (&cond->waiters_count);
+ p_mutex_unlock (mutex);
+
+ do {
+ ULONG post_count;
+
+ ulrc = DosWaitEventSem (cond->waiters_sema, SEM_INDEFINITE_WAIT);
+
+ if (ulrc == NO_ERROR) {
+ reset_ulrc = DosResetEventSem (cond->waiters_sema, &post_count);
+
+ if (P_UNLIKELY (reset_ulrc != NO_ERROR &&
+ reset_ulrc != ERROR_ALREADY_RESET))
+ P_WARNING ("PCondVariable::p_cond_variable_wait: DosResetEventSem() failed");
+ }
+ } while (ulrc == NO_ERROR &&
+ p_atomic_int_compare_and_exchange (&cond->signaled, 1, 0) == FALSE);
+
+ p_atomic_int_add (&cond->waiters_count, -1);
+ p_mutex_lock (mutex);
+ } while (ulrc == ERROR_INTERRUPT);
+
+ return (ulrc == NO_ERROR) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ pboolean result = TRUE;
+
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (p_atomic_int_get (&cond->waiters_count) > 0) {
+ ULONG post_count;
+ APIRET ulrc;
+
+ p_atomic_int_set (&cond->signaled, 1);
+
+ ulrc = DosPostEventSem (cond->waiters_sema);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR &&
+ ulrc != ERROR_ALREADY_POSTED &&
+ ulrc != ERROR_TOO_MANY_POSTS)) {
+ P_WARNING ("PCondVariable::p_cond_variable_signal: DosPostEventSem() failed");
+ result = FALSE;
+ }
+ }
+
+ return result;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ pboolean result = TRUE;
+
+ while (p_atomic_int_get (&cond->waiters_count) != 0) {
+ if (P_UNLIKELY (p_cond_variable_signal (cond) == FALSE))
+ result = FALSE;
+ }
+
+ return result;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-posix.c b/3rdparty/plibsys/src/pcondvariable-posix.c
new file mode 100644
index 0000000..54d7682
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-posix.c
@@ -0,0 +1,121 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcondvariable.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+
+struct PCondVariable_ {
+ pthread_cond_t hdl;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pthread_cond_init (&ret->hdl, NULL) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if (P_UNLIKELY (pthread_cond_destroy (&cond->hdl) != 0))
+ P_WARNING ("PCondVariable::p_cond_variable_free: pthread_cond_destroy() failed");
+
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ /* Cast is eligible since there is only one field in the PMutex structure */
+ if (P_UNLIKELY (pthread_cond_wait (&cond->hdl, (pthread_mutex_t *) mutex) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: pthread_cond_wait() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (pthread_cond_signal (&cond->hdl) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal: pthread_cond_signal() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (pthread_cond_broadcast (&cond->hdl) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast: thread_cond_broadcast() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-solaris.c b/3rdparty/plibsys/src/pcondvariable-solaris.c
new file mode 100644
index 0000000..53fdacf
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-solaris.c
@@ -0,0 +1,122 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcondvariable.h"
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <thread.h>
+#include <synch.h>
+
+struct PCondVariable_ {
+ cond_t hdl;
+};
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (cond_init (&ret->hdl, NULL, NULL) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ if (P_UNLIKELY (cond_destroy (&cond->hdl) != 0))
+ P_WARNING ("PCondVariable::p_cond_variable_free: cond_destroy() failed");
+
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ /* Cast is eligible since there is only one field in the PMutex structure */
+ if (P_UNLIKELY (cond_wait (&cond->hdl, (mutex_t *) mutex) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_wait: cond_wait() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (cond_signal (&cond->hdl) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_signal: cond_signal() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (cond_broadcast (&cond->hdl) != 0)) {
+ P_ERROR ("PCondVariable::p_cond_variable_broadcast: cond_broadcast() failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+p_cond_variable_init (void)
+{
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/pcondvariable-win.c b/3rdparty/plibsys/src/pcondvariable-win.c
new file mode 100644
index 0000000..0cf7dcb
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable-win.c
@@ -0,0 +1,312 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Taken from "Strategies for Implementing POSIX Condition Variables on Win32"
+ * by Douglas C. Schmidt and Irfan Pyarali.
+ * See: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ * See: https://github.com/python/cpython/blob/master/Python/condvar.h
+ */
+
+#include "patomic.h"
+#include "pmem.h"
+#include "pcondvariable.h"
+
+#include <stdlib.h>
+
+typedef VOID (WINAPI * InitializeConditionVariableFunc) (ppointer cv);
+typedef BOOL (WINAPI * SleepConditionVariableCSFunc) (ppointer cv, PCRITICAL_SECTION cs, DWORD ms);
+typedef VOID (WINAPI * WakeConditionVariableFunc) (ppointer cv);
+typedef VOID (WINAPI * WakeAllConditionVariableFunc) (ppointer cv);
+
+typedef pboolean (* PWin32CondInit) (PCondVariable *cond);
+typedef void (* PWin32CondClose) (PCondVariable *cond);
+typedef pboolean (* PWin32CondWait) (PCondVariable *cond, PMutex *mutex);
+typedef pboolean (* PWin32CondSignal) (PCondVariable *cond);
+typedef pboolean (* PWin32CondBrdcast) (PCondVariable *cond);
+
+static PWin32CondInit pp_cond_variable_init_func = NULL;
+static PWin32CondClose pp_cond_variable_close_func = NULL;
+static PWin32CondWait pp_cond_variable_wait_func = NULL;
+static PWin32CondSignal pp_cond_variable_signal_func = NULL;
+static PWin32CondBrdcast pp_cond_variable_brdcast_func = NULL;
+
+typedef struct PCondVariableVistaTable_ {
+ InitializeConditionVariableFunc cv_init;
+ SleepConditionVariableCSFunc cv_wait;
+ WakeConditionVariableFunc cv_wake;
+ WakeAllConditionVariableFunc cv_brdcast;
+} PCondVariableVistaTable;
+
+typedef struct PCondVariableXP_ {
+ HANDLE waiters_sema;
+ pint waiters_count;
+} PCondVariableXP;
+
+struct PCondVariable_ {
+ ppointer cv;
+};
+
+static PCondVariableVistaTable pp_cond_variable_vista_table = {NULL, NULL, NULL, NULL};
+
+/* CONDITION_VARIABLE routines */
+static pboolean pp_cond_variable_init_vista (PCondVariable *cond);
+static void pp_cond_variable_close_vista (PCondVariable *cond);
+static pboolean pp_cond_variable_wait_vista (PCondVariable *cond, PMutex *mutex);
+static pboolean pp_cond_variable_signal_vista (PCondVariable *cond);
+static pboolean pp_cond_variable_broadcast_vista (PCondVariable *cond);
+
+/* Windows XP emulation routines */
+static pboolean pp_cond_variable_init_xp (PCondVariable *cond);
+static void pp_cond_variable_close_xp (PCondVariable *cond);
+static pboolean pp_cond_variable_wait_xp (PCondVariable *cond, PMutex *mutex);
+static pboolean pp_cond_variable_signal_xp (PCondVariable *cond);
+static pboolean pp_cond_variable_broadcast_xp (PCondVariable *cond);
+
+/* CONDITION_VARIABLE routines */
+
+static pboolean
+pp_cond_variable_init_vista (PCondVariable *cond)
+{
+ pp_cond_variable_vista_table.cv_init (cond);
+
+ return TRUE;
+}
+
+static void
+pp_cond_variable_close_vista (PCondVariable *cond)
+{
+ P_UNUSED (cond);
+}
+
+static pboolean
+pp_cond_variable_wait_vista (PCondVariable *cond, PMutex *mutex)
+{
+ return pp_cond_variable_vista_table.cv_wait (cond,
+ (PCRITICAL_SECTION) mutex,
+ INFINITE) != 0 ? TRUE : FALSE;
+}
+
+static pboolean
+pp_cond_variable_signal_vista (PCondVariable *cond)
+{
+ pp_cond_variable_vista_table.cv_wake (cond);
+
+ return TRUE;
+}
+
+static pboolean
+pp_cond_variable_broadcast_vista (PCondVariable *cond)
+{
+ pp_cond_variable_vista_table.cv_brdcast (cond);
+
+ return TRUE;
+}
+
+/* Windows XP emulation routines */
+
+static pboolean
+pp_cond_variable_init_xp (PCondVariable *cond)
+{
+ PCondVariableXP *cv_xp;
+
+ if ((cond->cv = p_malloc0 (sizeof (PCondVariableXP))) == NULL) {
+ P_ERROR ("PCondVariable::pp_cond_variable_init_xp: failed to allocate memory (internal)");
+ return FALSE;
+ }
+
+ cv_xp = ((PCondVariableXP *) cond->cv);
+
+ cv_xp->waiters_count = 0;
+ cv_xp->waiters_sema = CreateSemaphoreA (NULL, 0, MAXLONG, NULL);
+
+ if (P_UNLIKELY (cv_xp->waiters_sema == NULL)) {
+ P_ERROR ("PCondVariable::pp_cond_variable_init_xp: failed to initialize semaphore");
+ p_free (cond->cv);
+ cond->cv = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_cond_variable_close_xp (PCondVariable *cond)
+{
+ CloseHandle (((PCondVariableXP *) cond->cv)->waiters_sema);
+ p_free (cond->cv);
+}
+
+static pboolean
+pp_cond_variable_wait_xp (PCondVariable *cond, PMutex *mutex)
+{
+ PCondVariableXP *cv_xp = ((PCondVariableXP *) cond->cv);
+ DWORD wait;
+
+ p_atomic_int_inc (&cv_xp->waiters_count);
+
+ p_mutex_unlock (mutex);
+ wait = WaitForSingleObjectEx (cv_xp->waiters_sema, INFINITE, FALSE);
+ p_mutex_lock (mutex);
+
+ if (wait != WAIT_OBJECT_0)
+ p_atomic_int_add (&cv_xp->waiters_count, -1);
+
+ return wait == WAIT_OBJECT_0 ? TRUE : FALSE;
+}
+
+static pboolean
+pp_cond_variable_signal_xp (PCondVariable *cond)
+{
+ PCondVariableXP *cv_xp = ((PCondVariableXP *) cond->cv);
+
+ if (p_atomic_int_get (&cv_xp->waiters_count) > 0) {
+ p_atomic_int_add (&cv_xp->waiters_count, -1);
+ return ReleaseSemaphore (cv_xp->waiters_sema, 1, 0) != 0 ? TRUE : FALSE;
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_cond_variable_broadcast_xp (PCondVariable *cond)
+{
+ PCondVariableXP *cv_xp = ((PCondVariableXP *) cond->cv);
+ pint waiters;
+
+ waiters = p_atomic_int_get (&cv_xp->waiters_count);
+
+ if (waiters > 0) {
+ p_atomic_int_set (&cv_xp->waiters_count, 0);
+ return ReleaseSemaphore (cv_xp->waiters_sema, waiters, 0) != 0 ? TRUE : FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API PCondVariable *
+p_cond_variable_new (void)
+{
+ PCondVariable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pp_cond_variable_init_func (ret) != TRUE)) {
+ P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_cond_variable_free (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return;
+
+ pp_cond_variable_close_func (cond);
+ p_free (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex)
+{
+ if (P_UNLIKELY (cond == NULL || mutex == NULL))
+ return FALSE;
+
+ return pp_cond_variable_wait_func (cond, mutex);
+}
+
+P_LIB_API pboolean
+p_cond_variable_signal (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ return pp_cond_variable_signal_func (cond);
+}
+
+P_LIB_API pboolean
+p_cond_variable_broadcast (PCondVariable *cond)
+{
+ if (P_UNLIKELY (cond == NULL))
+ return FALSE;
+
+ return pp_cond_variable_brdcast_func (cond);
+}
+
+void
+p_cond_variable_init (void)
+{
+ HMODULE hmodule;
+
+ hmodule = GetModuleHandleA ("kernel32.dll");
+
+ if (P_UNLIKELY (hmodule == NULL)) {
+ P_ERROR ("PCondVariable::p_cond_variable_init: failed to load kernel32.dll module");
+ return;
+ }
+
+ pp_cond_variable_vista_table.cv_init = (InitializeConditionVariableFunc) GetProcAddress (hmodule,
+ "InitializeConditionVariable");
+
+ if (P_LIKELY (pp_cond_variable_vista_table.cv_init != NULL)) {
+ pp_cond_variable_vista_table.cv_wait = (SleepConditionVariableCSFunc) GetProcAddress (hmodule,
+ "SleepConditionVariableCS");
+ pp_cond_variable_vista_table.cv_wake = (WakeConditionVariableFunc) GetProcAddress (hmodule,
+ "WakeConditionVariable");
+ pp_cond_variable_vista_table.cv_brdcast = (WakeAllConditionVariableFunc) GetProcAddress (hmodule,
+ "WakeAllConditionVariable");
+
+ pp_cond_variable_init_func = pp_cond_variable_init_vista;
+ pp_cond_variable_close_func = pp_cond_variable_close_vista;
+ pp_cond_variable_wait_func = pp_cond_variable_wait_vista;
+ pp_cond_variable_signal_func = pp_cond_variable_signal_vista;
+ pp_cond_variable_brdcast_func = pp_cond_variable_broadcast_vista;
+ } else {
+ pp_cond_variable_init_func = pp_cond_variable_init_xp;
+ pp_cond_variable_close_func = pp_cond_variable_close_xp;
+ pp_cond_variable_wait_func = pp_cond_variable_wait_xp;
+ pp_cond_variable_signal_func = pp_cond_variable_signal_xp;
+ pp_cond_variable_brdcast_func = pp_cond_variable_broadcast_xp;
+ }
+}
+
+void
+p_cond_variable_shutdown (void)
+{
+ memset (&pp_cond_variable_vista_table, 0, sizeof (pp_cond_variable_vista_table));
+
+ pp_cond_variable_init_func = NULL;
+ pp_cond_variable_close_func = NULL;
+ pp_cond_variable_wait_func = NULL;
+ pp_cond_variable_signal_func = NULL;
+ pp_cond_variable_brdcast_func = NULL;
+}
diff --git a/3rdparty/plibsys/src/pcondvariable.h b/3rdparty/plibsys/src/pcondvariable.h
new file mode 100644
index 0000000..d69c8b9
--- /dev/null
+++ b/3rdparty/plibsys/src/pcondvariable.h
@@ -0,0 +1,138 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pcondvariable.h
+ * @brief Condition variable
+ * @author Alexander Saprykin
+ *
+ * A condition variable is an inter-thread synchronization primitive, often
+ * used in the classical 'producers-consumers' concurrent data access models.
+ *
+ * The main idea is to notify waiting thread(s) for some events before they
+ * can enter a critical section. Hence the name of the primitive: a thread
+ * enters the critical section upon an accomplished condition. Compare it with a
+ * mutex where the thread enters the critical section as soon as no one holds a
+ * lock.
+ *
+ * Several threads can be notified at once, but only one of them can enter the
+ * critical section. The order of the threads in that case is implementation
+ * dependent.
+ *
+ * As the thread enters the critical section upon a condition it still requires
+ * a mutex to guard its code against concurrent access from other threads. The
+ * mutex provided in pair with a condition variable will be automatically locked
+ * on the condition, the thread should unlock it explicitly after leaving the
+ * critical section. That mutex is unlocked while waiting for the condition and
+ * should be locked prior calling the condition waiting routine.
+ *
+ * The waiting thread behavior: create a new condition variable with
+ * p_cond_variable_new(), create and lock a mutex before a critical section and
+ * wait for a signal from another thread on this condition variable
+ * using p_cond_variable_wait().
+ *
+ * The signaling thread behavior: upon reaching event time emit a signal with
+ * p_cond_variable_signal() to wake up a single waiting thread or
+ * p_cond_variable_broadcast() to wake up all the waiting threads.
+ *
+ * After emitting the signal only the one thread will get the locked mutex back
+ * to continue executing the critical section.
+ *
+ * It is implementation dependent whether a thread will receive a missed signal
+ * (when a notification from the one thread was emitted prior another thread has
+ * been called for waiting), so do not rely on this behavior.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCONDVARIABLE_H
+#define PLIBSYS_HEADER_PCONDVARIABLE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <pmutex.h>
+
+P_BEGIN_DECLS
+
+/** Condition variable opaque data structure. */
+typedef struct PCondVariable_ PCondVariable;
+
+/**
+ * @brief Creates a new #PCondVariable.
+ * @return Pointer to a newly created #PCondVariable structure, or NULL if
+ * failed.
+ * @since 0.0.1
+ */
+P_LIB_API PCondVariable * p_cond_variable_new (void);
+
+/**
+ * @brief Frees #PCondVariable structure.
+ * @param cond Condtion variable to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_cond_variable_free (PCondVariable *cond);
+
+/**
+ * @brief Waits for a signal on a given condition variable.
+ * @param cond Condition variable to wait on.
+ * @param mutex Locked mutex which will remain locked after waiting.
+ * @return TRUE on success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * The calling thread will sleep until the signal on @a cond arrived.
+ */
+P_LIB_API pboolean p_cond_variable_wait (PCondVariable *cond,
+ PMutex *mutex);
+
+/**
+ * @brief Emitts a signal on a given condition variable for one waiting thread.
+ * @param cond Condition variable to emit the signal on.
+ * @return TRUE on success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * After emitting the signal only the one thread waiting for it will be waken
+ * up. Do not rely on a queue concept for waiting threads. Though the
+ * implementation is intended to be much close to a queue, it's not fairly
+ * enough. Due that any thread can be waken up, even if it has just called
+ * p_cond_variable_wait() while there are other waiting threads.
+ */
+P_LIB_API pboolean p_cond_variable_signal (PCondVariable *cond);
+
+/**
+ * @brief Emitts a signal on a given condition variable for all the waiting
+ * threads.
+ * @param cond Condition variable to emit the signal on.
+ * @return TRUE on success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * After emitting the signal all the threads waiting for it will be waken up.
+ */
+P_LIB_API pboolean p_cond_variable_broadcast (PCondVariable *cond);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCONDVARIABLE_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-gost3411.c b/3rdparty/plibsys/src/pcryptohash-gost3411.c
new file mode 100644
index 0000000..9430453
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-gost3411.c
@@ -0,0 +1,484 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcryptohash-gost3411.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+struct PHashGOST3411_ {
+ puint32 buf[8]; /* Buffer to handle incoming data. */
+ puint32 hash[8]; /* State of calculated hash. */
+ puint32 len[8]; /* Length of hashed data, in bits. */
+ puint32 sum[8]; /* 256-bit sum of hashed data. */
+};
+
+static void pp_crypto_hash_gost3411_swap_bytes (puint32 *data, puint words);
+static void pp_crypto_hash_gost3411_sum_256 (puint32 a[8], const puint32 b[8]);
+static void pp_crypto_hash_gost3411_process (PHashGOST3411 *ctx, const puint32 data[8]);
+
+/* K block data from RFC4357 for GOST 28147-89 */
+/* static const puchar pp_crypto_hash_gost3411_K_block[8][16] = {
+ {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0, 0xD, 0x5},
+ {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4, 0xD, 0x1},
+ {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7, 0x1, 0x9},
+ {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8, 0x5, 0x6},
+ {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7, 0xA, 0x6},
+ {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF, 0xE, 0x6},
+ {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3, 0xB, 0xE},
+ {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7, 0xD, 0x4}
+}; */
+
+/* K block data used by Russian Central Bank (see RFC 4357, sec. 11.2) */
+/* static const puchar pp_crypto_hash_gost3411_K_block[8][16] = {
+ {0x4, 0xA, 0x9, 0x2, 0xD, 0x8, 0x0, 0xE, 0x6, 0xB, 0x1, 0xC, 0x7, 0xF, 0x5, 0x3},
+ {0xE, 0xB, 0x4, 0xC, 0x6, 0xD, 0xF, 0xA, 0x2, 0x3, 0x8, 0x1, 0x0, 0x7, 0x5, 0x9},
+ {0x5, 0x8, 0x1, 0xD, 0xA, 0x3, 0x4, 0x2, 0xE, 0xF, 0xC, 0x7, 0x6, 0x0, 0x9, 0xB},
+ {0x7, 0xD, 0xA, 0x1, 0x0, 0x8, 0x9, 0xF, 0xE, 0x4, 0x6, 0xC, 0xB, 0x2, 0x5, 0x3},
+ {0x6, 0xC, 0x7, 0x1, 0x5, 0xF, 0xD, 0x8, 0x4, 0xA, 0x9, 0xE, 0x0, 0x3, 0xB, 0x2},
+ {0x4, 0xB, 0xA, 0x0, 0x7, 0x2, 0x1, 0xD, 0x3, 0x6, 0x8, 0x5, 0x9, 0xC, 0xF, 0xE},
+ {0xD, 0xB, 0x4, 0x1, 0x3, 0xF, 0x5, 0x9, 0x0, 0xA, 0xE, 0x7, 0x6, 0x8, 0x2, 0xC},
+ {0x1, 0xF, 0xD, 0x0, 0x5, 0x7, 0xA, 0x4, 0x9, 0x2, 0x3, 0xE, 0x6, 0xB, 0x8, 0xC}
+}; */
+
+ /* K block data id-GostR3411-94-CryptoProParamSet (see RFC 4357, sec. 11.2) */
+ static const puchar pp_crypto_hash_gost3411_K_block[8][16] = {
+ {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2, 0xB, 0xF},
+ {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE, 0xA, 0x8},
+ {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA, 0x8, 0xD},
+ {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB, 0x9, 0x3},
+ {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD, 0x3, 0x5},
+ {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE, 0xC, 0x3},
+ {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2, 0x9, 0xB},
+ {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0, 0x2, 0xC}
+ };
+
+/* GOST 28147-89 transformation to generate keys */
+#define P_GOST_28147_ROUND(N, key) \
+{ \
+ puint32 CM1; \
+ \
+ CM1 = (N)[0] + (key); \
+ \
+ CM1 = ((puint32) pp_crypto_hash_gost3411_K_block [0][CM1 & 0xF] \
+ | (puint32) pp_crypto_hash_gost3411_K_block [1][(CM1 >> 4) & 0xF] << 4 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [2][(CM1 >> 8) & 0xF] << 8 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [3][(CM1 >> 12) & 0xF] << 12 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [4][(CM1 >> 16) & 0xF] << 16 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [5][(CM1 >> 20) & 0xF] << 20 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [6][(CM1 >> 24) & 0xF] << 24 \
+ | (puint32) pp_crypto_hash_gost3411_K_block [7][(CM1 >> 28) & 0xF] << 28); \
+ \
+ CM1 = ((CM1 << 11) | (CM1 >> 21)) ^ (N)[1]; \
+ (N)[1] = (N)[0]; \
+ (N)[0] = CM1; \
+}
+
+/* Core GOST 28147-89 transformation */
+#define P_GOST_28147_E(data, key, out) \
+{ \
+ puint32 N[2]; \
+ \
+ memcpy (N, data, 8); \
+ \
+ P_GOST_28147_ROUND (N, (key)[0]); \
+ P_GOST_28147_ROUND (N, (key)[1]); \
+ P_GOST_28147_ROUND (N, (key)[2]); \
+ P_GOST_28147_ROUND (N, (key)[3]); \
+ P_GOST_28147_ROUND (N, (key)[4]); \
+ P_GOST_28147_ROUND (N, (key)[5]); \
+ P_GOST_28147_ROUND (N, (key)[6]); \
+ P_GOST_28147_ROUND (N, (key)[7]); \
+ \
+ P_GOST_28147_ROUND (N, (key)[0]); \
+ P_GOST_28147_ROUND (N, (key)[1]); \
+ P_GOST_28147_ROUND (N, (key)[2]); \
+ P_GOST_28147_ROUND (N, (key)[3]); \
+ P_GOST_28147_ROUND (N, (key)[4]); \
+ P_GOST_28147_ROUND (N, (key)[5]); \
+ P_GOST_28147_ROUND (N, (key)[6]); \
+ P_GOST_28147_ROUND (N, (key)[7]); \
+ \
+ P_GOST_28147_ROUND (N, (key)[0]); \
+ P_GOST_28147_ROUND (N, (key)[1]); \
+ P_GOST_28147_ROUND (N, (key)[2]); \
+ P_GOST_28147_ROUND (N, (key)[3]); \
+ P_GOST_28147_ROUND (N, (key)[4]); \
+ P_GOST_28147_ROUND (N, (key)[5]); \
+ P_GOST_28147_ROUND (N, (key)[6]); \
+ P_GOST_28147_ROUND (N, (key)[7]); \
+ \
+ P_GOST_28147_ROUND (N, (key)[7]); \
+ P_GOST_28147_ROUND (N, (key)[6]); \
+ P_GOST_28147_ROUND (N, (key)[5]); \
+ P_GOST_28147_ROUND (N, (key)[4]); \
+ P_GOST_28147_ROUND (N, (key)[3]); \
+ P_GOST_28147_ROUND (N, (key)[2]); \
+ P_GOST_28147_ROUND (N, (key)[1]); \
+ P_GOST_28147_ROUND (N, (key)[0]); \
+ \
+ (out)[0] = N[1]; \
+ (out)[1] = N[0]; \
+}
+
+/* P transformation from GOST R 34.11-94 */
+#define P_GOST_3411_P(data, out) \
+{ \
+ (out)[0] = ((data) [0] & 0x000000FF) \
+ | (((data)[2] << 8) & 0x0000FF00) \
+ | (((data)[4] << 16) & 0x00FF0000) \
+ | (((data)[6] << 24) & 0xFF000000); \
+ (out)[1] = (((data)[0] >> 8) & 0x000000FF) \
+ | ((data) [2] & 0x0000FF00) \
+ | (((data)[4] << 8) & 0x00FF0000) \
+ | (((data)[6] << 16) & 0xFF000000); \
+ (out)[2] = (((data)[0] >> 16) & 0x000000FF) \
+ | (((data)[2] >> 8) & 0x0000FF00) \
+ | ((data) [4] & 0x00FF0000) \
+ | (((data)[6] << 8) & 0xFF000000); \
+ (out)[3] = (((data)[0] >> 24) & 0x000000FF) \
+ | (((data)[2] >> 16) & 0x0000FF00) \
+ | (((data)[4] >> 8) & 0x00FF0000) \
+ | ((data) [6] & 0xFF000000); \
+ (out)[4] = ((data) [1] & 0x000000FF) \
+ | (((data)[3] << 8) & 0x0000FF00) \
+ | (((data)[5] << 16) & 0x00FF0000) \
+ | (((data)[7] << 24) & 0xFF000000); \
+ (out)[5] = (((data)[1] >> 8) & 0x000000FF) \
+ | ((data) [3] & 0x0000FF00) \
+ | (((data)[5] << 8) & 0x00FF0000) \
+ | (((data)[7] << 16) & 0xFF000000); \
+ (out)[6] = (((data)[1] >> 16) & 0x000000FF) \
+ | (((data)[3] >> 8) & 0x0000FF00) \
+ | ((data) [5] & 0x00FF0000) \
+ | (((data)[7] << 8) & 0xFF000000); \
+ (out)[7] = (((data)[1] >> 24) & 0x000000FF) \
+ | (((data)[3] >> 16) & 0x0000FF00) \
+ | (((data)[5] >> 8) & 0x00FF0000) \
+ | ((data) [7] & 0xFF000000); \
+}
+
+static void
+pp_crypto_hash_gost3411_swap_bytes (puint32 *data,
+ puint words)
+{
+#ifndef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT32_TO_LE (*data);
+ ++data;
+ }
+#endif
+}
+
+/* 256-bit sum */
+static void
+pp_crypto_hash_gost3411_sum_256 (puint32 a[8],
+ const puint32 b[8])
+{
+ puint i;
+ puint32 old;
+ pboolean carry;
+
+ carry = FALSE;
+ for (i = 0; i < 8; ++i) {
+ old = a[i];
+ a[i] = a[i] + b[i] + (carry ? 1 : 0);
+ carry = (a[i] < old || a[i] < b[i]) ? TRUE : FALSE;
+ }
+}
+
+/* Core GOST R 34.11-94 transformation */
+static void pp_crypto_hash_gost3411_process (PHashGOST3411 *ctx,
+ const puint32 data[8])
+{
+ puint32 U[8], V[8], W[8], S[8], K[4][8];
+
+ memcpy (U, ctx->hash, 32);
+ memcpy (V, data, 32);
+
+ /* Generate first key: P (U xor V) */
+ W[0] = U[0] ^ V[0];
+ W[1] = U[1] ^ V[1];
+ W[2] = U[2] ^ V[2];
+ W[3] = U[3] ^ V[3];
+ W[4] = U[4] ^ V[4];
+ W[5] = U[5] ^ V[5];
+ W[6] = U[6] ^ V[6];
+ W[7] = U[7] ^ V[7];
+
+ P_GOST_3411_P (W, K[0]);
+
+ /* Generate second key: P (A (U) xor A^2 (V)) */
+ W[0] = U[2] ^ V[4];
+ W[1] = U[3] ^ V[5];
+ W[2] = U[4] ^ V[6];
+ W[3] = U[5] ^ V[7];
+ W[4] = U[6] ^ (V[0] ^= V[2]);
+ W[5] = U[7] ^ (V[1] ^= V[3]);
+ W[6] = (U[0] ^= U[2]) ^ (V[2] ^= V[4]);
+ W[7] = (U[1] ^= U[3]) ^ (V[3] ^= V[5]);
+
+ P_GOST_3411_P (W, K[1]);
+
+ /* Generate third key: P ((A^2 (U) + C3) xor A^4 (V)) */
+ /* C3 = FF00FFFF 000000FF FF0000FF 00FFFF00 00FF00FF 00FF00FF FF00FF00 FF00FF00 */
+ U[2] ^= U[4] ^ 0x000000FF;
+ U[3] ^= U[5] ^ 0xFF00FFFF;
+ U[4] ^= 0xFF00FF00;
+ U[5] ^= 0xFF00FF00;
+ U[6] ^= 0x00FF00FF;
+ U[7] ^= 0x00FF00FF;
+ U[0] ^= 0x00FFFF00;
+ U[1] ^= 0xFF0000FF;
+
+ W[0] = U[4] ^ V[0];
+ W[2] = U[6] ^ V[2];
+ W[4] = U[0] ^ (V[4] ^= V[6]);
+ W[6] = U[2] ^ (V[6] ^= V[0]);
+ W[1] = U[5] ^ V[1];
+ W[3] = U[7] ^ V[3];
+ W[5] = U[1] ^ (V[5] ^= V[7]);
+ W[7] = U[3] ^ (V[7] ^= V[1]);
+
+ P_GOST_3411_P (W, K[2]);
+
+ /* Generate forth key: P (A (A^2 (U) xor C3) xor A^6 (V)) */
+ W[0] = U[6] ^ V[4];
+ W[1] = U[7] ^ V[5];
+ W[2] = U[0] ^ V[6];
+ W[3] = U[1] ^ V[7];
+ W[4] = U[2] ^ (V[0] ^= V[2]);
+ W[5] = U[3] ^ (V[1] ^= V[3]);
+ W[6] = (U[4] ^= U[6]) ^ (V[2] ^= V[4]);
+ W[7] = (U[5] ^= U[7]) ^ (V[3] ^= V[5]);
+
+ P_GOST_3411_P (W, K[3]);
+
+ /* Perform GOST 28147-89 encryption */
+ P_GOST_28147_E (ctx->hash, K[0], S);
+ P_GOST_28147_E (ctx->hash + 2, K[1], S + 2);
+ P_GOST_28147_E (ctx->hash + 4, K[2], S + 4);
+ P_GOST_28147_E (ctx->hash + 6, K[3], S + 6);
+
+ /* Step hash function: H (M, Hprev) = PSI^61 (Hprev xor PSI (M xor PSI^12 (S))) */
+
+ /* (12 rounds of LFSR) xor M */
+ U[0] = data[0] ^ S[6];
+
+ U[1] = data[1] ^ S[7];
+
+ U[2] = data[2] ^ (S[0] & 0x0000FFFF) ^ (S[0] >> 16) ^ (S[0] << 16)
+ ^ (S[1] & 0x0000FFFF) ^ (S[1] >> 16) ^ (S[2] << 16)
+ ^ (S[7] & 0xFFFF0000) ^ (S[6] << 16) ^ (S[7] >> 16)
+ ^ S[6];
+
+ U[3] = data[3] ^ (S[0] & 0x0000FFFF) ^ (S[0] << 16) ^ (S[2] << 16)
+ ^ (S[1] & 0x0000FFFF) ^ (S[1] << 16) ^ (S[1] >> 16)
+ ^ (S[7] & 0x0000FFFF) ^ (S[2] >> 16) ^ (S[3] << 16)
+ ^ (S[6] << 16) ^ (S[6] >> 16) ^ (S[7] << 16)
+ ^ (S[7] >> 16) ^ S[6];
+
+ U[4] = data[4] ^ (S[0] & 0xFFFF0000) ^ (S[0] << 16) ^ (S[0] >> 16)
+ ^ (S[1] & 0xFFFF0000) ^ (S[1] >> 16) ^ (S[2] << 16)
+ ^ (S[7] & 0x0000FFFF) ^ (S[3] << 16) ^ (S[3] >> 16)
+ ^ (S[4] << 16) ^ (S[6] << 16) ^ (S[6] >> 16)
+ ^ (S[2] >> 16) ^ (S[7] << 16) ^ (S[7] >> 16);
+
+ U[5] = data[5] ^ (S[0] & 0xFFFF0000) ^ (S[0] >> 16) ^ (S[0] << 16)
+ ^ (S[1] & 0x0000FFFF) ^ (S[7] >> 16) ^ (S[2] >> 16)
+ ^ (S[7] & 0xFFFF0000) ^ (S[3] >> 16) ^ (S[4] << 16)
+ ^ (S[4] >> 16) ^ (S[5] << 16) ^ (S[6] << 16)
+ ^ (S[6] >> 16) ^ (S[3] << 16) ^ (S[7] << 16)
+ ^ S[2];
+
+ U[6] = data[6] ^ (S[4] >> 16) ^ (S[1] >> 16) ^ (S[2] << 16)
+ ^ (S[7] << 16) ^ (S[3] >> 16) ^ (S[4] << 16)
+ ^ (S[5] << 16) ^ (S[5] >> 16) ^ (S[6] << 16)
+ ^ (S[6] >> 16) ^ S[6] ^ S[0]
+ ^ S[3];
+
+ U[7] = data[7] ^ (S[0] & 0xFFFF0000) ^ (S[0] << 16) ^ (S[1] << 16)
+ ^ (S[1] & 0x0000FFFF) ^ (S[2] >> 16) ^ (S[3] << 16)
+ ^ (S[7] & 0x0000FFFF) ^ (S[4] >> 16) ^ (S[5] << 16)
+ ^ (S[5] >> 16) ^ (S[6] >> 16) ^ (S[7] << 16)
+ ^ (S[7] >> 16) ^ S[4];
+
+ /* (1 round of LFSR) xor Hprev */
+ V[0] = ctx->hash[0] ^ (U[1] << 16) ^ (U[0] >> 16);
+ V[1] = ctx->hash[1] ^ (U[2] << 16) ^ (U[1] >> 16);
+ V[2] = ctx->hash[2] ^ (U[3] << 16) ^ (U[2] >> 16);
+ V[3] = ctx->hash[3] ^ (U[4] << 16) ^ (U[3] >> 16);
+ V[4] = ctx->hash[4] ^ (U[5] << 16) ^ (U[4] >> 16);
+ V[5] = ctx->hash[5] ^ (U[6] << 16) ^ (U[5] >> 16);
+ V[6] = ctx->hash[6] ^ (U[7] << 16) ^ (U[6] >> 16);
+ V[7] = ctx->hash[7] ^ (U[7] >> 16)
+ ^ (U[0] << 16) ^ (U[1] & 0xFFFF0000)
+ ^ (U[1] << 16) ^ (U[7] & 0xFFFF0000)
+ ^ (U[6] << 16) ^ (U[0] & 0xFFFF0000);
+
+ /* Final 61 rounds of LFSR */
+ ctx->hash[0] = (V[0] & 0xFFFF0000) ^ (V[0] << 16) ^ (V[0] >> 16)
+ ^ (V[1] & 0xFFFF0000) ^ (V[1] >> 16) ^ (V[2] << 16)
+ ^ (V[7] & 0x0000FFFF) ^ (V[3] >> 16) ^ (V[4] << 16)
+ ^ (V[5] >> 16) ^ (V[6] >> 16) ^ (V[7] << 16)
+ ^ (V[7] >> 16) ^ V[5];
+ ctx->hash[1] = (V[0] & 0xFFFF0000) ^ (V[0] << 16) ^ (V[0] >> 16)
+ ^ (V[1] & 0x0000FFFF) ^ (V[2] >> 16) ^ (V[3] << 16)
+ ^ (V[7] & 0xFFFF0000) ^ (V[4] >> 16) ^ (V[5] << 16)
+ ^ (V[6] << 16) ^ (V[7] >> 16) ^ V[6]
+ ^ V[2] ;
+ ctx->hash[2] = (V[0] & 0x0000FFFF) ^ (V[0] << 16) ^ (V[1] << 16)
+ ^ (V[7] & 0x0000FFFF) ^ (V[1] >> 16) ^ (V[2] << 16)
+ ^ (V[1] & 0xFFFF0000) ^ (V[3] >> 16) ^ (V[4] << 16)
+ ^ (V[5] >> 16) ^ (V[6] >> 16) ^ (V[7] << 16)
+ ^ (V[7] >> 16) ^ V[3] ^ V[6];
+ ctx->hash[3] = (V[0] & 0xFFFF0000) ^ (V[0] << 16) ^ (V[0] >> 16)
+ ^ (V[1] & 0xFFFF0000) ^ (V[1] >> 16) ^ (V[2] << 16)
+ ^ (V[7] & 0x0000FFFF) ^ (V[2] >> 16) ^ (V[3] << 16)
+ ^ (V[4] >> 16) ^ (V[5] << 16) ^ (V[6] << 16)
+ ^ (V[7] >> 16) ^ V[2] ^ V[4];
+ ctx->hash[4] = (V[0] >> 16) ^ (V[1] << 16) ^ (V[2] >> 16)
+ ^ (V[3] << 16) ^ (V[3] >> 16) ^ (V[4] << 16)
+ ^ (V[5] >> 16) ^ (V[6] << 16) ^ (V[6] >> 16)
+ ^ (V[7] << 16) ^ V[1] ^ V[2]
+ ^ V[3] ^ V[5];
+ ctx->hash[5] = (V[0] & 0xFFFF0000) ^ (V[0] << 16) ^ (V[1] << 16)
+ ^ (V[1] & 0xFFFF0000) ^ (V[1] >> 16) ^ (V[2] << 16)
+ ^ (V[7] & 0xFFFF0000) ^ (V[3] >> 16) ^ (V[4] << 16)
+ ^ (V[4] >> 16) ^ (V[5] << 16) ^ (V[6] << 16)
+ ^ (V[6] >> 16) ^ (V[7] << 16) ^ (V[7] >> 16)
+ ^ V[2] ^ V[3] ^ V[4]
+ ^ V[6];
+ ctx->hash[6] = (V[2] >> 16) ^ (V[3] << 16) ^ (V[4] >> 16)
+ ^ (V[5] << 16) ^ (V[5] >> 16) ^ (V[6] << 16)
+ ^ (V[6] >> 16) ^ (V[7] << 16) ^ V[7]
+ ^ V[0] ^ V[2] ^ V[3]
+ ^ V[4] ^ V[5] ^ V[6];
+ ctx->hash[7] = (V[0] >> 16) ^ (V[1] << 16) ^ (V[1] >> 16)
+ ^ (V[2] << 16) ^ (V[3] >> 16) ^ (V[4] << 16)
+ ^ (V[5] >> 16) ^ (V[6] << 16) ^ (V[6] >> 16)
+ ^ (V[7] << 16) ^ V[7] ^ V[0]
+ ^ V[3] ^ V[4] ^ V[5];
+}
+
+PHashGOST3411 *
+p_crypto_hash_gost3411_new (void)
+{
+ PHashGOST3411 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashGOST3411))) == NULL))
+ return NULL;
+
+ p_crypto_hash_gost3411_reset (ret);
+
+ return ret;
+}
+
+void
+p_crypto_hash_gost3411_update (PHashGOST3411 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill, len256[8];
+
+ left = (ctx->len[0] & 0xFF) >> 3;
+ to_fill = 32 - left;
+
+ memset (len256, 0, 32);
+ len256[0] = (puint32) (len << 3);
+ len256[1] = (puint32) (len >> 29);
+
+ pp_crypto_hash_gost3411_sum_256 (ctx->len, len256);
+
+ if (left && (puint32) len >= to_fill) {
+ memcpy ((pchar *) ctx->buf + left, data, to_fill);
+ pp_crypto_hash_gost3411_swap_bytes (ctx->buf, 8);
+ pp_crypto_hash_gost3411_process (ctx, ctx->buf);
+ pp_crypto_hash_gost3411_sum_256 (ctx->sum, ctx->buf);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= 32) {
+ memcpy (ctx->buf, data, 32);
+ pp_crypto_hash_gost3411_swap_bytes (ctx->buf, 8);
+ pp_crypto_hash_gost3411_process (ctx, ctx->buf);
+ pp_crypto_hash_gost3411_sum_256 (ctx->sum, ctx->buf);
+
+ data += 32;
+ len -= 32;
+ }
+
+ if (len > 0)
+ memcpy ((pchar *) ctx->buf + left, data, len);
+}
+
+void
+p_crypto_hash_gost3411_finish (PHashGOST3411 *ctx)
+{
+ puint32 left, last;
+
+ left = ctx->len[0] & 0xFF;
+ last = 32 - (left >> 3);
+
+ if (last % 32 != 0) {
+ memset ((pchar *) ctx->buf + (left >> 3), 0, last);
+ pp_crypto_hash_gost3411_swap_bytes (ctx->buf, 8);
+ pp_crypto_hash_gost3411_process (ctx, ctx->buf);
+ pp_crypto_hash_gost3411_sum_256 (ctx->sum, ctx->buf);
+ }
+
+ pp_crypto_hash_gost3411_process (ctx, ctx->len);
+ pp_crypto_hash_gost3411_process (ctx, ctx->sum);
+
+ pp_crypto_hash_gost3411_swap_bytes (ctx->hash, 8);
+}
+
+const puchar *
+p_crypto_hash_gost3411_digest (PHashGOST3411 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_gost3411_reset (PHashGOST3411 *ctx)
+{
+ memset (ctx->buf, 0, 32);
+ memset (ctx->hash, 0, 32);
+ memset (ctx->len, 0, 32);
+ memset (ctx->sum, 0, 32);
+}
+
+void
+p_crypto_hash_gost3411_free (PHashGOST3411 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-gost3411.h b/3rdparty/plibsys/src/pcryptohash-gost3411.h
new file mode 100644
index 0000000..dd0f0ad
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-gost3411.h
@@ -0,0 +1,53 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* GOST R 34.11-94 interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHGOST3411_H
+#define PLIBSYS_HEADER_PCRYPTOHASHGOST3411_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashGOST3411_ PHashGOST3411;
+
+PHashGOST3411 * p_crypto_hash_gost3411_new (void);
+void p_crypto_hash_gost3411_update (PHashGOST3411 *ctx,
+ const puchar *data,
+ psize len);
+void p_crypto_hash_gost3411_finish (PHashGOST3411 *ctx);
+const puchar * p_crypto_hash_gost3411_digest (PHashGOST3411 *ctx);
+void p_crypto_hash_gost3411_reset (PHashGOST3411 *ctx);
+void p_crypto_hash_gost3411_free (PHashGOST3411 *ctx);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHGOST3411_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-md5.c b/3rdparty/plibsys/src/pcryptohash-md5.c
new file mode 100644
index 0000000..ee09033
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-md5.c
@@ -0,0 +1,273 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcryptohash-md5.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+struct PHashMD5_ {
+ union buf_ {
+ puchar buf[64];
+ puint32 buf_w[16];
+ } buf;
+ puint32 hash[4];
+
+ puint32 len_high;
+ puint32 len_low;
+};
+
+static const puchar pp_crypto_hash_md5_pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static void pp_crypto_hash_md5_swap_bytes (puint32 *data, puint words);
+static void pp_crypto_hash_md5_process (PHashMD5 *ctx, const puint32 data[16]);
+
+#define P_MD5_ROTL(val, shift) ((val) << (shift) | (val) >> (32 - (shift)))
+
+#define P_MD5_F(x, y, z) (z ^ (x & (y ^ z)))
+#define P_MD5_G(x, y, z) P_MD5_F (z, x, y)
+#define P_MD5_H(x, y, z) (x ^ y ^ z)
+#define P_MD5_I(x, y, z) (y ^ (x | (~z)))
+
+#define P_MD5_ROUND_0(a, b, c, d, k, i, s) \
+ a += P_MD5_F (b, c, d) + data[k] + i, a = P_MD5_ROTL (a, s) + b
+
+#define P_MD5_ROUND_1(a, b, c, d, k, i, s) \
+ a += P_MD5_G (b, c, d) + data[k] + i, a = P_MD5_ROTL (a, s) + b
+
+
+#define P_MD5_ROUND_2(a, b, c, d, k, i, s) \
+ a += P_MD5_H (b, c, d) + data[k] + i, a = P_MD5_ROTL (a, s) + b
+
+#define P_MD5_ROUND_3(a, b, c, d, k, i, s) \
+ a += P_MD5_I (b, c, d) + data[k] + i, a = P_MD5_ROTL (a, s) + b
+
+static void
+pp_crypto_hash_md5_swap_bytes (puint32 *data,
+ puint words)
+{
+#ifndef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT32_TO_LE (*data);
+ ++data;
+ }
+#endif
+}
+
+static void
+pp_crypto_hash_md5_process (PHashMD5 *ctx,
+ const puint32 data[16])
+{
+ puint32 A, B, C, D;
+
+ A = ctx->hash[0];
+ B = ctx->hash[1];
+ C = ctx->hash[2];
+ D = ctx->hash[3];
+
+ P_MD5_ROUND_0 (A, B, C, D, 0, 0xD76AA478, 7);
+ P_MD5_ROUND_0 (D, A, B, C, 1, 0xE8C7B756, 12);
+ P_MD5_ROUND_0 (C, D, A, B, 2, 0x242070DB, 17);
+ P_MD5_ROUND_0 (B, C, D, A, 3, 0xC1BDCEEE, 22);
+ P_MD5_ROUND_0 (A, B, C, D, 4, 0xF57C0FAF, 7);
+ P_MD5_ROUND_0 (D, A, B, C, 5, 0x4787C62A, 12);
+ P_MD5_ROUND_0 (C, D, A, B, 6, 0xA8304613, 17);
+ P_MD5_ROUND_0 (B, C, D, A, 7, 0xFD469501, 22);
+ P_MD5_ROUND_0 (A, B, C, D, 8, 0x698098D8, 7);
+ P_MD5_ROUND_0 (D, A, B, C, 9, 0x8B44F7AF, 12);
+ P_MD5_ROUND_0 (C, D, A, B, 10, 0xFFFF5BB1, 17);
+ P_MD5_ROUND_0 (B, C, D, A, 11, 0x895CD7BE, 22);
+ P_MD5_ROUND_0 (A, B, C, D, 12, 0x6B901122, 7);
+ P_MD5_ROUND_0 (D, A, B, C, 13, 0xFD987193, 12);
+ P_MD5_ROUND_0 (C, D, A, B, 14, 0xA679438E, 17);
+ P_MD5_ROUND_0 (B, C, D, A, 15, 0x49B40821, 22);
+
+ P_MD5_ROUND_1 (A, B, C, D, 1, 0xF61E2562, 5);
+ P_MD5_ROUND_1 (D, A, B, C, 6, 0xC040B340, 9);
+ P_MD5_ROUND_1 (C, D, A, B, 11, 0x265E5A51, 14);
+ P_MD5_ROUND_1 (B, C, D, A, 0, 0xE9B6C7AA, 20);
+ P_MD5_ROUND_1 (A, B, C, D, 5, 0xD62F105D, 5);
+ P_MD5_ROUND_1 (D, A, B, C, 10, 0x02441453, 9);
+ P_MD5_ROUND_1 (C, D, A, B, 15, 0xD8A1E681, 14);
+ P_MD5_ROUND_1 (B, C, D, A, 4, 0xE7D3FBC8, 20);
+ P_MD5_ROUND_1 (A, B, C, D, 9, 0x21E1CDE6, 5);
+ P_MD5_ROUND_1 (D, A, B, C, 14, 0xC33707D6, 9);
+ P_MD5_ROUND_1 (C, D, A, B, 3, 0xF4D50D87, 14);
+ P_MD5_ROUND_1 (B, C, D, A, 8, 0x455A14ED, 20);
+ P_MD5_ROUND_1 (A, B, C, D, 13, 0xA9E3E905, 5);
+ P_MD5_ROUND_1 (D, A, B, C, 2, 0xFCEFA3F8, 9);
+ P_MD5_ROUND_1 (C, D, A, B, 7, 0x676F02D9, 14);
+ P_MD5_ROUND_1 (B, C, D, A, 12, 0x8D2A4C8A, 20);
+
+ P_MD5_ROUND_2 (A, B, C, D, 5, 0xFFFA3942, 4);
+ P_MD5_ROUND_2 (D, A, B, C, 8, 0x8771F681, 11);
+ P_MD5_ROUND_2 (C, D, A, B, 11, 0x6D9D6122, 16);
+ P_MD5_ROUND_2 (B, C, D, A, 14, 0xFDE5380C, 23);
+ P_MD5_ROUND_2 (A, B, C, D, 1, 0xA4BEEA44, 4);
+ P_MD5_ROUND_2 (D, A, B, C, 4, 0x4BDECFA9, 11);
+ P_MD5_ROUND_2 (C, D, A, B, 7, 0xF6BB4B60, 16);
+ P_MD5_ROUND_2 (B, C, D, A, 10, 0xBEBFBC70, 23);
+ P_MD5_ROUND_2 (A, B, C, D, 13, 0x289B7EC6, 4);
+ P_MD5_ROUND_2 (D, A, B, C, 0, 0xEAA127FA, 11);
+ P_MD5_ROUND_2 (C, D, A, B, 3, 0xD4EF3085, 16);
+ P_MD5_ROUND_2 (B, C, D, A, 6, 0x04881D05, 23);
+ P_MD5_ROUND_2 (A, B, C, D, 9, 0xD9D4D039, 4);
+ P_MD5_ROUND_2 (D, A, B, C, 12, 0xE6DB99E5, 11);
+ P_MD5_ROUND_2 (C, D, A, B, 15, 0x1FA27CF8, 16);
+ P_MD5_ROUND_2 (B, C, D, A, 2, 0xC4AC5665, 23);
+
+ P_MD5_ROUND_3 (A, B, C, D, 0, 0xF4292244, 6);
+ P_MD5_ROUND_3 (D, A, B, C, 7, 0x432AFF97, 10);
+ P_MD5_ROUND_3 (C, D, A, B, 14, 0xAB9423A7, 15);
+ P_MD5_ROUND_3 (B, C, D, A, 5, 0xFC93A039, 21);
+ P_MD5_ROUND_3 (A, B, C, D, 12, 0x655B59C3, 6);
+ P_MD5_ROUND_3 (D, A, B, C, 3, 0x8F0CCC92, 10);
+ P_MD5_ROUND_3 (C, D, A, B, 10, 0xFFEFF47D, 15);
+ P_MD5_ROUND_3 (B, C, D, A, 1, 0x85845DD1, 21);
+ P_MD5_ROUND_3 (A, B, C, D, 8, 0x6FA87E4F, 6);
+ P_MD5_ROUND_3 (D, A, B, C, 15, 0xFE2CE6E0, 10);
+ P_MD5_ROUND_3 (C, D, A, B, 6, 0xA3014314, 15);
+ P_MD5_ROUND_3 (B, C, D, A, 13, 0x4E0811A1, 21);
+ P_MD5_ROUND_3 (A, B, C, D, 4, 0xF7537E82, 6);
+ P_MD5_ROUND_3 (D, A, B, C, 11, 0xBD3AF235, 10);
+ P_MD5_ROUND_3 (C, D, A, B, 2, 0x2AD7D2BB, 15);
+ P_MD5_ROUND_3 (B, C, D, A, 9, 0xEB86D391, 21);
+
+ ctx->hash[0] += A;
+ ctx->hash[1] += B;
+ ctx->hash[2] += C;
+ ctx->hash[3] += D;
+}
+
+void
+p_crypto_hash_md5_reset (PHashMD5 *ctx)
+{
+ memset (ctx->buf.buf, 0, 64);
+
+ ctx->len_low = 0;
+ ctx->len_high = 0;
+
+ ctx->hash[0] = 0x67452301;
+ ctx->hash[1] = 0xEFCDAB89;
+ ctx->hash[2] = 0x98BADCFE;
+ ctx->hash[3] = 0x10325476;
+}
+
+PHashMD5 *
+p_crypto_hash_md5_new (void)
+{
+ PHashMD5 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashMD5))) == NULL))
+ return NULL;
+
+ p_crypto_hash_md5_reset (ret);
+
+ return ret;
+}
+
+void
+p_crypto_hash_md5_update (PHashMD5 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill;
+
+ left = ctx->len_low & 0x3F;
+ to_fill = 64 - left;
+
+ ctx->len_low += (puint32) len;
+
+ if (ctx->len_low < (puint32) len)
+ ++ctx->len_high;
+
+ if (left && (puint32) len >= to_fill) {
+ memcpy (ctx->buf.buf + left, data, to_fill);
+ pp_crypto_hash_md5_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_md5_process (ctx, ctx->buf.buf_w);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= 64) {
+ memcpy (ctx->buf.buf, data, 64);
+ pp_crypto_hash_md5_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_md5_process (ctx, ctx->buf.buf_w);
+
+ data += 64;
+ len -= 64;
+ }
+
+ if (len > 0)
+ memcpy (ctx->buf.buf + left, data, len);
+}
+
+void
+p_crypto_hash_md5_finish (PHashMD5 *ctx)
+{
+ puint32 high, low;
+ pint left, last;
+
+ left = ctx->len_low & 0x3F;
+ last = (left < 56) ? (56 - left) : (120 - left);
+
+ low = ctx->len_low << 3;
+ high = ctx->len_high << 3
+ | ctx->len_low >> 29;
+
+ if (last > 0)
+ p_crypto_hash_md5_update (ctx, pp_crypto_hash_md5_pad, (psize) last);
+
+ ctx->buf.buf_w[14] = low;
+ ctx->buf.buf_w[15] = high;
+
+ pp_crypto_hash_md5_swap_bytes (ctx->buf.buf_w, 14);
+ pp_crypto_hash_md5_process (ctx, ctx->buf.buf_w);
+
+ pp_crypto_hash_md5_swap_bytes (ctx->hash, 4);
+}
+
+const puchar *
+p_crypto_hash_md5_digest (PHashMD5 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_md5_free (PHashMD5 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-md5.h b/3rdparty/plibsys/src/pcryptohash-md5.h
new file mode 100644
index 0000000..142eee0
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-md5.h
@@ -0,0 +1,51 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* MD5 interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHMD5_H
+#define PLIBSYS_HEADER_PCRYPTOHASHMD5_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashMD5_ PHashMD5;
+
+PHashMD5 * p_crypto_hash_md5_new (void);
+void p_crypto_hash_md5_update (PHashMD5 *ctx, const puchar *data, psize len);
+void p_crypto_hash_md5_finish (PHashMD5 *ctx);
+const puchar * p_crypto_hash_md5_digest (PHashMD5 *ctx);
+void p_crypto_hash_md5_reset (PHashMD5 *ctx);
+void p_crypto_hash_md5_free (PHashMD5 *ctx);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHMD5_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-sha1.c b/3rdparty/plibsys/src/pcryptohash-sha1.c
new file mode 100644
index 0000000..62e826c
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha1.c
@@ -0,0 +1,321 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "pmem.h"
+#include "pcryptohash-sha1.h"
+
+struct PHashSHA1_ {
+ union buf_ {
+ puchar buf[64];
+ puint32 buf_w[16];
+ } buf;
+ puint32 hash[5];
+
+ puint32 len_high;
+ puint32 len_low;
+};
+
+static const puchar pp_crypto_hash_sha1_pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static void pp_crypto_hash_sha1_swap_bytes (puint32 *data, puint words);
+static void pp_crypto_hash_sha1_process (PHashSHA1 *ctx, const puint32 data[16]);
+
+#define P_SHA1_ROTL(val, shift) ((val) << (shift) | (val) >> (32 - (shift)))
+
+#define P_SHA1_F1(x, y, z) ((x & y) | ((~x) & z))
+#define P_SHA1_F2(x, y, z) (x ^ y ^ z)
+#define P_SHA1_F3(x, y, z) ((x & y) | (x & z) | (y & z))
+
+#define P_SHA1_W(W, i) \
+( \
+ (W)[i & 0x0F] = P_SHA1_ROTL ( \
+ (W)[(i - 3) & 0x0F] \
+ ^ (W)[(i - 8) & 0x0F] \
+ ^ (W)[(i - 14) & 0x0F] \
+ ^ (W)[(i - 16) & 0x0F], \
+ 1) \
+)
+
+#define P_SHA1_ROUND_0(a, b, c, d, e, w) \
+{ \
+ e += P_SHA1_ROTL (a, 5) + P_SHA1_F1 (b, c, d) \
+ + 0x5A827999 + w; \
+ b = P_SHA1_ROTL (b, 30); \
+}
+
+#define P_SHA1_ROUND_1(a, b, c, d, e, w) \
+{ \
+ e += P_SHA1_ROTL (a, 5) + P_SHA1_F2 (b, c, d) \
+ + 0x6ED9EBA1 + w; \
+ b = P_SHA1_ROTL (b, 30); \
+}
+
+#define P_SHA1_ROUND_2(a, b, c, d, e, w) \
+{ \
+ e += P_SHA1_ROTL (a, 5) + P_SHA1_F3 (b, c, d) \
+ + 0x8F1BBCDC + w; \
+ b = P_SHA1_ROTL (b, 30); \
+}
+
+#define P_SHA1_ROUND_3(a, b, c, d, e, w) \
+{ \
+ e += P_SHA1_ROTL (a, 5) + P_SHA1_F2 (b, c, d) \
+ + 0xCA62C1D6 + w; \
+ b = P_SHA1_ROTL (b, 30); \
+}
+
+static void
+pp_crypto_hash_sha1_swap_bytes (puint32 *data,
+ puint words)
+{
+#ifdef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT32_TO_BE (*data);
+ ++data;
+ }
+#endif
+}
+
+static void
+pp_crypto_hash_sha1_process (PHashSHA1 *ctx,
+ const puint32 data[16])
+{
+ puint32 W[16], A, B, C, D, E;
+
+ if (P_UNLIKELY (ctx == NULL))
+ return;
+
+ memcpy (W, data, 64);
+
+ A = ctx->hash[0];
+ B = ctx->hash[1];
+ C = ctx->hash[2];
+ D = ctx->hash[3];
+ E = ctx->hash[4];
+
+ P_SHA1_ROUND_0 (A, B, C, D, E, W[0]);
+ P_SHA1_ROUND_0 (E, A, B, C, D, W[1]);
+ P_SHA1_ROUND_0 (D, E, A, B, C, W[2]);
+ P_SHA1_ROUND_0 (C, D, E, A, B, W[3]);
+ P_SHA1_ROUND_0 (B, C, D, E, A, W[4]);
+ P_SHA1_ROUND_0 (A, B, C, D, E, W[5]);
+ P_SHA1_ROUND_0 (E, A, B, C, D, W[6]);
+ P_SHA1_ROUND_0 (D, E, A, B, C, W[7]);
+ P_SHA1_ROUND_0 (C, D, E, A, B, W[8]);
+ P_SHA1_ROUND_0 (B, C, D, E, A, W[9]);
+ P_SHA1_ROUND_0 (A, B, C, D, E, W[10]);
+ P_SHA1_ROUND_0 (E, A, B, C, D, W[11]);
+ P_SHA1_ROUND_0 (D, E, A, B, C, W[12]);
+ P_SHA1_ROUND_0 (C, D, E, A, B, W[13]);
+ P_SHA1_ROUND_0 (B, C, D, E, A, W[14]);
+ P_SHA1_ROUND_0 (A, B, C, D, E, W[15]);
+ P_SHA1_ROUND_0 (E, A, B, C, D, P_SHA1_W (W, 16));
+ P_SHA1_ROUND_0 (D, E, A, B, C, P_SHA1_W (W, 17));
+ P_SHA1_ROUND_0 (C, D, E, A, B, P_SHA1_W (W, 18));
+ P_SHA1_ROUND_0 (B, C, D, E, A, P_SHA1_W (W, 19));
+
+ P_SHA1_ROUND_1 (A, B, C, D, E, P_SHA1_W (W, 20));
+ P_SHA1_ROUND_1 (E, A, B, C, D, P_SHA1_W (W, 21));
+ P_SHA1_ROUND_1 (D, E, A, B, C, P_SHA1_W (W, 22));
+ P_SHA1_ROUND_1 (C, D, E, A, B, P_SHA1_W (W, 23));
+ P_SHA1_ROUND_1 (B, C, D, E, A, P_SHA1_W (W, 24));
+ P_SHA1_ROUND_1 (A, B, C, D, E, P_SHA1_W (W, 25));
+ P_SHA1_ROUND_1 (E, A, B, C, D, P_SHA1_W (W, 26));
+ P_SHA1_ROUND_1 (D, E, A, B, C, P_SHA1_W (W, 27));
+ P_SHA1_ROUND_1 (C, D, E, A, B, P_SHA1_W (W, 28));
+ P_SHA1_ROUND_1 (B, C, D, E, A, P_SHA1_W (W, 29));
+ P_SHA1_ROUND_1 (A, B, C, D, E, P_SHA1_W (W, 30));
+ P_SHA1_ROUND_1 (E, A, B, C, D, P_SHA1_W (W, 31));
+ P_SHA1_ROUND_1 (D, E, A, B, C, P_SHA1_W (W, 32));
+ P_SHA1_ROUND_1 (C, D, E, A, B, P_SHA1_W (W, 33));
+ P_SHA1_ROUND_1 (B, C, D, E, A, P_SHA1_W (W, 34));
+ P_SHA1_ROUND_1 (A, B, C, D, E, P_SHA1_W (W, 35));
+ P_SHA1_ROUND_1 (E, A, B, C, D, P_SHA1_W (W, 36));
+ P_SHA1_ROUND_1 (D, E, A, B, C, P_SHA1_W (W, 37));
+ P_SHA1_ROUND_1 (C, D, E, A, B, P_SHA1_W (W, 38));
+ P_SHA1_ROUND_1 (B, C, D, E, A, P_SHA1_W (W, 39));
+
+ P_SHA1_ROUND_2 (A, B, C, D, E, P_SHA1_W (W, 40));
+ P_SHA1_ROUND_2 (E, A, B, C, D, P_SHA1_W (W, 41));
+ P_SHA1_ROUND_2 (D, E, A, B, C, P_SHA1_W (W, 42));
+ P_SHA1_ROUND_2 (C, D, E, A, B, P_SHA1_W (W, 43));
+ P_SHA1_ROUND_2 (B, C, D, E, A, P_SHA1_W (W, 44));
+ P_SHA1_ROUND_2 (A, B, C, D, E, P_SHA1_W (W, 45));
+ P_SHA1_ROUND_2 (E, A, B, C, D, P_SHA1_W (W, 46));
+ P_SHA1_ROUND_2 (D, E, A, B, C, P_SHA1_W (W, 47));
+ P_SHA1_ROUND_2 (C, D, E, A, B, P_SHA1_W (W, 48));
+ P_SHA1_ROUND_2 (B, C, D, E, A, P_SHA1_W (W, 49));
+ P_SHA1_ROUND_2 (A, B, C, D, E, P_SHA1_W (W, 50));
+ P_SHA1_ROUND_2 (E, A, B, C, D, P_SHA1_W (W, 51));
+ P_SHA1_ROUND_2 (D, E, A, B, C, P_SHA1_W (W, 52));
+ P_SHA1_ROUND_2 (C, D, E, A, B, P_SHA1_W (W, 53));
+ P_SHA1_ROUND_2 (B, C, D, E, A, P_SHA1_W (W, 54));
+ P_SHA1_ROUND_2 (A, B, C, D, E, P_SHA1_W (W, 55));
+ P_SHA1_ROUND_2 (E, A, B, C, D, P_SHA1_W (W, 56));
+ P_SHA1_ROUND_2 (D, E, A, B, C, P_SHA1_W (W, 57));
+ P_SHA1_ROUND_2 (C, D, E, A, B, P_SHA1_W (W, 58));
+ P_SHA1_ROUND_2 (B, C, D, E, A, P_SHA1_W (W, 59));
+
+ P_SHA1_ROUND_3 (A, B, C, D, E, P_SHA1_W (W, 60));
+ P_SHA1_ROUND_3 (E, A, B, C, D, P_SHA1_W (W, 61));
+ P_SHA1_ROUND_3 (D, E, A, B, C, P_SHA1_W (W, 62));
+ P_SHA1_ROUND_3 (C, D, E, A, B, P_SHA1_W (W, 63));
+ P_SHA1_ROUND_3 (B, C, D, E, A, P_SHA1_W (W, 64));
+ P_SHA1_ROUND_3 (A, B, C, D, E, P_SHA1_W (W, 65));
+ P_SHA1_ROUND_3 (E, A, B, C, D, P_SHA1_W (W, 66));
+ P_SHA1_ROUND_3 (D, E, A, B, C, P_SHA1_W (W, 67));
+ P_SHA1_ROUND_3 (C, D, E, A, B, P_SHA1_W (W, 68));
+ P_SHA1_ROUND_3 (B, C, D, E, A, P_SHA1_W (W, 69));
+ P_SHA1_ROUND_3 (A, B, C, D, E, P_SHA1_W (W, 70));
+ P_SHA1_ROUND_3 (E, A, B, C, D, P_SHA1_W (W, 71));
+ P_SHA1_ROUND_3 (D, E, A, B, C, P_SHA1_W (W, 72));
+ P_SHA1_ROUND_3 (C, D, E, A, B, P_SHA1_W (W, 73));
+ P_SHA1_ROUND_3 (B, C, D, E, A, P_SHA1_W (W, 74));
+ P_SHA1_ROUND_3 (A, B, C, D, E, P_SHA1_W (W, 75));
+ P_SHA1_ROUND_3 (E, A, B, C, D, P_SHA1_W (W, 76));
+ P_SHA1_ROUND_3 (D, E, A, B, C, P_SHA1_W (W, 77));
+ P_SHA1_ROUND_3 (C, D, E, A, B, P_SHA1_W (W, 78));
+ P_SHA1_ROUND_3 (B, C, D, E, A, P_SHA1_W (W, 79));
+
+ ctx->hash[0] += A;
+ ctx->hash[1] += B;
+ ctx->hash[2] += C;
+ ctx->hash[3] += D;
+ ctx->hash[4] += E;
+}
+
+void
+p_crypto_hash_sha1_reset (PHashSHA1 *ctx)
+{
+ memset (ctx->buf.buf, 0, 64);
+
+ ctx->len_low = 0;
+ ctx->len_high = 0;
+
+ ctx->hash[0] = 0x67452301;
+ ctx->hash[1] = 0xEFCDAB89;
+ ctx->hash[2] = 0x98BADCFE;
+ ctx->hash[3] = 0x10325476;
+ ctx->hash[4] = 0xC3D2E1F0;
+}
+
+PHashSHA1 *
+p_crypto_hash_sha1_new (void)
+{
+ PHashSHA1 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashSHA1))) == NULL))
+ return NULL;
+
+ p_crypto_hash_sha1_reset (ret);
+
+ return ret;
+}
+
+void
+p_crypto_hash_sha1_update (PHashSHA1 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill;
+
+ left = ctx->len_low & 0x3F;
+ to_fill = 64 - left;
+
+ ctx->len_low += (puint32) len;
+
+ if (ctx->len_low < (puint32) len)
+ ++ctx->len_high;
+
+ if (left && (puint32) len >= to_fill) {
+ memcpy (ctx->buf.buf + left, data, to_fill);
+ pp_crypto_hash_sha1_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha1_process (ctx, ctx->buf.buf_w);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= 64) {
+ memcpy (ctx->buf.buf, data, 64);
+ pp_crypto_hash_sha1_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha1_process (ctx, ctx->buf.buf_w);
+
+ data += 64;
+ len -= 64;
+ }
+
+ if (len > 0)
+ memcpy (ctx->buf.buf + left, data, len);
+}
+
+void
+p_crypto_hash_sha1_finish (PHashSHA1 *ctx)
+{
+ puint32 high, low;
+ pint left, last;
+
+ left = ctx->len_low & 0x3F;
+ last = (left < 56) ? (56 - left) : (120 - left);
+
+ low = ctx->len_low << 3;
+ high = ctx->len_high << 3
+ | ctx->len_low >> 29;
+
+ if (last > 0)
+ p_crypto_hash_sha1_update (ctx, pp_crypto_hash_sha1_pad, (psize) last);
+
+ ctx->buf.buf_w[14] = high;
+ ctx->buf.buf_w[15] = low;
+
+ pp_crypto_hash_sha1_swap_bytes (ctx->buf.buf_w, 14);
+ pp_crypto_hash_sha1_process (ctx, ctx->buf.buf_w);
+
+ pp_crypto_hash_sha1_swap_bytes (ctx->hash, 5);
+}
+
+const puchar *
+p_crypto_hash_sha1_digest (PHashSHA1 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_sha1_free (PHashSHA1 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-sha1.h b/3rdparty/plibsys/src/pcryptohash-sha1.h
new file mode 100644
index 0000000..cecbc0d
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha1.h
@@ -0,0 +1,51 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* SHA1 interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHSHA1_H
+#define PLIBSYS_HEADER_PCRYPTOHASHSHA1_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashSHA1_ PHashSHA1;
+
+PHashSHA1 * p_crypto_hash_sha1_new (void);
+void p_crypto_hash_sha1_update (PHashSHA1 *ctx, const puchar *data, psize len);
+void p_crypto_hash_sha1_finish (PHashSHA1 *ctx);
+const puchar * p_crypto_hash_sha1_digest (PHashSHA1 *ctx);
+void p_crypto_hash_sha1_reset (PHashSHA1 *ctx);
+void p_crypto_hash_sha1_free (PHashSHA1 *ctx);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHSHA1_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-sha2-256.c b/3rdparty/plibsys/src/pcryptohash-sha2-256.c
new file mode 100644
index 0000000..29bb0ba
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha2-256.c
@@ -0,0 +1,286 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "pmem.h"
+#include "pcryptohash-sha2-256.h"
+
+struct PHashSHA2_256_ {
+ union buf_ {
+ puchar buf[64];
+ puint32 buf_w[16];
+ } buf;
+ puint32 hash[8];
+
+ puint32 len_high;
+ puint32 len_low;
+
+ pboolean is224;
+};
+
+static const puchar pp_crypto_hash_sha2_256_pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const puint32 pp_crypto_hash_sha2_256_K[] = {
+ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
+ 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
+ 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
+ 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
+ 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
+ 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
+ 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
+ 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
+ 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
+ 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
+ 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
+ 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
+ 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
+ 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
+ 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
+ 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
+};
+
+static void pp_crypto_hash_sha2_256_swap_bytes (puint32 *data, puint words);
+static void pp_crypto_hash_sha2_256_process (PHashSHA2_256 *ctx, const puint32 data[16]);
+static PHashSHA2_256 * pp_crypto_hash_sha2_256_new_internal (pboolean is224);
+
+#define P_SHA2_256_SHR(val, shift) (((val) & 0xFFFFFFFF) >> (shift))
+#define P_SHA2_256_ROTR(val, shift) (P_SHA2_256_SHR(val, shift) | ((val) << (32 - (shift))))
+
+#define P_SHA2_256_S0(x) (P_SHA2_256_ROTR (x, 7) ^ P_SHA2_256_ROTR (x, 18) ^ P_SHA2_256_SHR (x, 3))
+#define P_SHA2_256_S1(x) (P_SHA2_256_ROTR (x, 17) ^ P_SHA2_256_ROTR (x, 19) ^ P_SHA2_256_SHR (x, 10))
+#define P_SHA2_256_S2(x) (P_SHA2_256_ROTR (x, 2) ^ P_SHA2_256_ROTR (x, 13) ^ P_SHA2_256_ROTR (x, 22))
+#define P_SHA2_256_S3(x) (P_SHA2_256_ROTR (x, 6) ^ P_SHA2_256_ROTR (x, 11) ^ P_SHA2_256_ROTR (x, 25))
+
+#define P_SHA2_256_F0(x, y, z) ((x & y) | (z & (x | y)))
+#define P_SHA2_256_F1(x, y, z) (z ^ (x & (y ^ z)))
+
+#define P_SHA2_256_R(t) \
+( \
+ W[t] = P_SHA2_256_S1 (W[t - 2]) + W[t - 7] + \
+ P_SHA2_256_S0 (W[t - 15]) + W[t - 16] \
+)
+
+#define P_SHA2_256_P(a, b, c, d, e, f, g, h, x, K) \
+{ \
+ tmp_sum1 = h + P_SHA2_256_S3 (e) + P_SHA2_256_F1 (e, f, g) + K + x; \
+ tmp_sum2 = P_SHA2_256_S2 (a) + P_SHA2_256_F0 (a, b, c); \
+ d += tmp_sum1; \
+ h = tmp_sum1 + tmp_sum2; \
+}
+
+static void
+pp_crypto_hash_sha2_256_swap_bytes (puint32 *data,
+ puint words)
+{
+#ifdef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT32_TO_BE (*data);
+ ++data;
+ }
+#endif
+}
+
+static void
+pp_crypto_hash_sha2_256_process (PHashSHA2_256 *ctx,
+ const puint32 data[16])
+{
+ puint32 tmp_sum1, tmp_sum2;
+ puint32 W[64];
+ puint32 A[8];
+ puint i;
+
+ for (i = 0; i < 8; i++)
+ A[i] = ctx->hash[i];
+
+ memcpy (W, data, 64);
+
+ for (i = 0; i < 16; i += 8) {
+ P_SHA2_256_P (A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], pp_crypto_hash_sha2_256_K[i + 0]);
+ P_SHA2_256_P (A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], pp_crypto_hash_sha2_256_K[i + 1]);
+ P_SHA2_256_P (A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], pp_crypto_hash_sha2_256_K[i + 2]);
+ P_SHA2_256_P (A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], pp_crypto_hash_sha2_256_K[i + 3]);
+ P_SHA2_256_P (A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], pp_crypto_hash_sha2_256_K[i + 4]);
+ P_SHA2_256_P (A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], pp_crypto_hash_sha2_256_K[i + 5]);
+ P_SHA2_256_P (A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], pp_crypto_hash_sha2_256_K[i + 6]);
+ P_SHA2_256_P (A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], pp_crypto_hash_sha2_256_K[i + 7]);
+ }
+
+ for (i = 16; i < 64; i += 8) {
+ P_SHA2_256_P (A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], P_SHA2_256_R (i + 0), pp_crypto_hash_sha2_256_K[i + 0]);
+ P_SHA2_256_P (A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], P_SHA2_256_R (i + 1), pp_crypto_hash_sha2_256_K[i + 1]);
+ P_SHA2_256_P (A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], P_SHA2_256_R (i + 2), pp_crypto_hash_sha2_256_K[i + 2]);
+ P_SHA2_256_P (A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], P_SHA2_256_R (i + 3), pp_crypto_hash_sha2_256_K[i + 3]);
+ P_SHA2_256_P (A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], P_SHA2_256_R (i + 4), pp_crypto_hash_sha2_256_K[i + 4]);
+ P_SHA2_256_P (A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], P_SHA2_256_R (i + 5), pp_crypto_hash_sha2_256_K[i + 5]);
+ P_SHA2_256_P (A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], P_SHA2_256_R (i + 6), pp_crypto_hash_sha2_256_K[i + 6]);
+ P_SHA2_256_P (A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], P_SHA2_256_R (i + 7), pp_crypto_hash_sha2_256_K[i + 7]);
+ }
+
+ for (i = 0; i < 8; i++)
+ ctx->hash[i] += A[i];
+}
+
+static PHashSHA2_256 *
+pp_crypto_hash_sha2_256_new_internal (pboolean is224)
+{
+ PHashSHA2_256 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashSHA2_256))) == NULL))
+ return NULL;
+
+ ret->is224 = is224;
+
+ p_crypto_hash_sha2_256_reset (ret);
+
+ return ret;
+}
+
+void
+p_crypto_hash_sha2_256_reset (PHashSHA2_256 *ctx)
+{
+ memset (ctx->buf.buf, 0, 64);
+
+ ctx->len_low = 0;
+ ctx->len_high = 0;
+
+ if (ctx->is224 == FALSE) {
+ /* SHA2-256 */
+ ctx->hash[0] = 0x6A09E667;
+ ctx->hash[1] = 0xBB67AE85;
+ ctx->hash[2] = 0x3C6EF372;
+ ctx->hash[3] = 0xA54FF53A;
+ ctx->hash[4] = 0x510E527F;
+ ctx->hash[5] = 0x9B05688C;
+ ctx->hash[6] = 0x1F83D9AB;
+ ctx->hash[7] = 0x5BE0CD19;
+ } else {
+ /* SHA2-224 */
+ ctx->hash[0] = 0xC1059ED8;
+ ctx->hash[1] = 0x367CD507;
+ ctx->hash[2] = 0x3070DD17;
+ ctx->hash[3] = 0xF70E5939;
+ ctx->hash[4] = 0xFFC00B31;
+ ctx->hash[5] = 0x68581511;
+ ctx->hash[6] = 0x64F98FA7;
+ ctx->hash[7] = 0xBEFA4FA4;
+ }
+}
+
+PHashSHA2_256 *
+p_crypto_hash_sha2_256_new (void)
+{
+ return pp_crypto_hash_sha2_256_new_internal (FALSE);
+}
+
+PHashSHA2_256 *
+p_crypto_hash_sha2_224_new (void)
+{
+ return pp_crypto_hash_sha2_256_new_internal (TRUE);
+}
+
+void
+p_crypto_hash_sha2_256_update (PHashSHA2_256 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill;
+
+ left = ctx->len_low & 0x3F;
+ to_fill = 64 - left;
+
+ ctx->len_low += (puint32) len;
+
+ if (ctx->len_low < (puint32) len)
+ ++ctx->len_high;
+
+ if (left && (puint32) len >= to_fill) {
+ memcpy (ctx->buf.buf + left, data, to_fill);
+ pp_crypto_hash_sha2_256_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha2_256_process (ctx, ctx->buf.buf_w);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= 64) {
+ memcpy (ctx->buf.buf, data, 64);
+ pp_crypto_hash_sha2_256_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha2_256_process (ctx, ctx->buf.buf_w);
+
+ data += 64;
+ len -= 64;
+ }
+
+ if (len > 0)
+ memcpy (ctx->buf.buf + left, data, len);
+}
+
+void
+p_crypto_hash_sha2_256_finish (PHashSHA2_256 *ctx)
+{
+ puint32 high, low;
+ pint left, last;
+
+ left = ctx->len_low & 0x3F;
+ last = (left < 56) ? (56 - left) : (120 - left);
+
+ low = ctx->len_low << 3;
+ high = ctx->len_high << 3
+ | ctx->len_low >> 29;
+
+ if (last > 0)
+ p_crypto_hash_sha2_256_update (ctx, pp_crypto_hash_sha2_256_pad, (psize) last);
+
+ ctx->buf.buf_w[14] = high;
+ ctx->buf.buf_w[15] = low;
+
+ pp_crypto_hash_sha2_256_swap_bytes (ctx->buf.buf_w, 14);
+ pp_crypto_hash_sha2_256_process (ctx, ctx->buf.buf_w);
+
+ pp_crypto_hash_sha2_256_swap_bytes (ctx->hash, ctx->is224 == FALSE ? 8 : 7);
+}
+
+const puchar *
+p_crypto_hash_sha2_256_digest (PHashSHA2_256 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_sha2_256_free (PHashSHA2_256 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-sha2-256.h b/3rdparty/plibsys/src/pcryptohash-sha2-256.h
new file mode 100644
index 0000000..0255011
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha2-256.h
@@ -0,0 +1,59 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* SHA2-256 interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHSHA2_256_H
+#define PLIBSYS_HEADER_PCRYPTOHASHSHA2_256_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashSHA2_256_ PHashSHA2_256;
+
+PHashSHA2_256 * p_crypto_hash_sha2_256_new (void);
+void p_crypto_hash_sha2_256_update (PHashSHA2_256 *ctx, const puchar *data, psize len);
+void p_crypto_hash_sha2_256_finish (PHashSHA2_256 *ctx);
+const puchar * p_crypto_hash_sha2_256_digest (PHashSHA2_256 *ctx);
+void p_crypto_hash_sha2_256_reset (PHashSHA2_256 *ctx);
+void p_crypto_hash_sha2_256_free (PHashSHA2_256 *ctx);
+
+PHashSHA2_256 * p_crypto_hash_sha2_224_new (void);
+
+#define p_crypto_hash_sha2_224_update p_crypto_hash_sha2_256_update
+#define p_crypto_hash_sha2_224_finish p_crypto_hash_sha2_256_finish
+#define p_crypto_hash_sha2_224_digest p_crypto_hash_sha2_256_digest
+#define p_crypto_hash_sha2_224_reset p_crypto_hash_sha2_256_reset
+#define p_crypto_hash_sha2_224_free p_crypto_hash_sha2_256_free
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHSHA2_256_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-sha2-512.c b/3rdparty/plibsys/src/pcryptohash-sha2-512.c
new file mode 100644
index 0000000..7864da3
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha2-512.c
@@ -0,0 +1,300 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "pmem.h"
+#include "pcryptohash-sha2-512.h"
+
+struct PHashSHA2_512_ {
+ union buf_ {
+ puchar buf[128];
+ puint64 buf_w[16];
+ } buf;
+ puint64 hash[8];
+
+ puint64 len_high;
+ puint64 len_low;
+
+ pboolean is384;
+};
+
+static const puchar pp_crypto_hash_sha2_512_pad[128] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const puint64 pp_crypto_hash_sha2_512_K[] = {
+ 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
+ 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
+ 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
+ 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
+ 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
+ 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
+ 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
+ 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
+ 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
+ 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
+ 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
+ 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
+ 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
+ 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
+ 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
+ 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
+ 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
+ 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
+ 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
+ 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
+ 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
+ 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
+ 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
+ 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
+ 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
+ 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
+ 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
+ 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
+ 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
+ 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
+ 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
+ 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
+ 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
+ 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
+ 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
+ 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
+ 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
+ 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
+ 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
+ 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
+};
+
+static void pp_crypto_hash_sha2_512_swap_bytes (puint64 *data, puint words);
+static void pp_crypto_hash_sha2_512_process (PHashSHA2_512 *ctx, const puint64 data[16]);
+static PHashSHA2_512 * pp_crypto_hash_sha2_512_new_internal (pboolean is384);
+
+#define P_SHA2_512_SHR(val, shift) ((val) >> (shift))
+#define P_SHA2_512_ROTR(val, shift) (P_SHA2_512_SHR(val, shift) | ((val) << (64 - (shift))))
+
+#define P_SHA2_512_S0(x) (P_SHA2_512_ROTR (x, 1) ^ P_SHA2_512_ROTR (x, 8) ^ P_SHA2_512_SHR (x, 7))
+#define P_SHA2_512_S1(x) (P_SHA2_512_ROTR (x, 19) ^ P_SHA2_512_ROTR (x, 61) ^ P_SHA2_512_SHR (x, 6))
+#define P_SHA2_512_S2(x) (P_SHA2_512_ROTR (x, 28) ^ P_SHA2_512_ROTR (x, 34) ^ P_SHA2_512_ROTR (x, 39))
+#define P_SHA2_512_S3(x) (P_SHA2_512_ROTR (x, 14) ^ P_SHA2_512_ROTR (x, 18) ^ P_SHA2_512_ROTR (x, 41))
+
+#define P_SHA2_512_F0(x, y, z) ((x & y) | (z & (x | y)))
+#define P_SHA2_512_F1(x, y, z) (z ^ (x & (y ^ z)))
+
+#define P_SHA2_512_P(a, b, c, d, e, f, g, h, x, K) \
+{ \
+ tmp_sum1 = h + P_SHA2_512_S3 (e) + P_SHA2_512_F1 (e, f, g) + K + x; \
+ tmp_sum2 = P_SHA2_512_S2 (a) + P_SHA2_512_F0 (a, b, c); \
+ d += tmp_sum1; \
+ h = tmp_sum1 + tmp_sum2; \
+}
+
+static void
+pp_crypto_hash_sha2_512_swap_bytes (puint64 *data,
+ puint words)
+{
+#ifdef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT64_TO_BE (*data);
+ ++data;
+ }
+#endif
+}
+
+static void
+pp_crypto_hash_sha2_512_process (PHashSHA2_512 *ctx,
+ const puint64 data[16])
+{
+ puint64 tmp_sum1, tmp_sum2;
+ puint64 W[80];
+ puint64 A[8];
+ puint i;
+
+ for (i = 0; i < 8; ++i)
+ A[i] = ctx->hash[i];
+
+ memcpy (W, data, 128);
+
+ for (i = 16; i < 80; ++i)
+ W[i] = P_SHA2_512_S1 (W[i - 2]) + W[i - 7] + P_SHA2_512_S0 (W[i - 15]) + W[i - 16];
+
+ for (i = 0; i < 80; i += 8) {
+ P_SHA2_512_P (A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], pp_crypto_hash_sha2_512_K[i + 0]);
+ P_SHA2_512_P (A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], pp_crypto_hash_sha2_512_K[i + 1]);
+ P_SHA2_512_P (A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], pp_crypto_hash_sha2_512_K[i + 2]);
+ P_SHA2_512_P (A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], pp_crypto_hash_sha2_512_K[i + 3]);
+ P_SHA2_512_P (A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], pp_crypto_hash_sha2_512_K[i + 4]);
+ P_SHA2_512_P (A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], pp_crypto_hash_sha2_512_K[i + 5]);
+ P_SHA2_512_P (A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], pp_crypto_hash_sha2_512_K[i + 6]);
+ P_SHA2_512_P (A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], pp_crypto_hash_sha2_512_K[i + 7]);
+ }
+
+ for (i = 0; i < 8; ++i)
+ ctx->hash[i] += A[i];
+}
+
+static PHashSHA2_512 *
+pp_crypto_hash_sha2_512_new_internal (pboolean is384)
+{
+ PHashSHA2_512 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashSHA2_512))) == NULL))
+ return NULL;
+
+ ret->is384 = is384;
+
+ p_crypto_hash_sha2_512_reset (ret);
+
+ return ret;
+}
+
+void
+p_crypto_hash_sha2_512_reset (PHashSHA2_512 *ctx)
+{
+ memset (ctx->buf.buf, 0, 128);
+
+ ctx->len_low = 0;
+ ctx->len_high = 0;
+
+ if (ctx->is384 == FALSE) {
+ /* SHA2-512 */
+ ctx->hash[0] = 0x6A09E667F3BCC908ULL;
+ ctx->hash[1] = 0xBB67AE8584CAA73BULL;
+ ctx->hash[2] = 0x3C6EF372FE94F82BULL;
+ ctx->hash[3] = 0xA54FF53A5F1D36F1ULL;
+ ctx->hash[4] = 0x510E527FADE682D1ULL;
+ ctx->hash[5] = 0x9B05688C2B3E6C1FULL;
+ ctx->hash[6] = 0x1F83D9ABFB41BD6BULL;
+ ctx->hash[7] = 0x5BE0CD19137E2179ULL;
+ } else {
+ /* SHA2-384 */
+ ctx->hash[0] = 0xCBBB9D5DC1059ED8ULL;
+ ctx->hash[1] = 0x629A292A367CD507ULL;
+ ctx->hash[2] = 0x9159015A3070DD17ULL;
+ ctx->hash[3] = 0x152FECD8F70E5939ULL;
+ ctx->hash[4] = 0x67332667FFC00B31ULL;
+ ctx->hash[5] = 0x8EB44A8768581511ULL;
+ ctx->hash[6] = 0xDB0C2E0D64F98FA7ULL;
+ ctx->hash[7] = 0x47B5481DBEFA4FA4ULL;
+ }
+}
+
+PHashSHA2_512 *
+p_crypto_hash_sha2_512_new (void)
+{
+ return pp_crypto_hash_sha2_512_new_internal (FALSE);
+}
+
+PHashSHA2_512 *
+p_crypto_hash_sha2_384_new (void)
+{
+ return pp_crypto_hash_sha2_512_new_internal (TRUE);
+}
+
+void
+p_crypto_hash_sha2_512_update (PHashSHA2_512 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill;
+
+ left = (puint32) (ctx->len_low & 0x7F);
+ to_fill = 128 - left;
+
+ ctx->len_low += (puint64) len;
+
+ if (ctx->len_low < (puint64) len)
+ ++ctx->len_high;
+
+ if (left && (puint64) len >= to_fill) {
+ memcpy (ctx->buf.buf + left, data, to_fill);
+ pp_crypto_hash_sha2_512_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha2_512_process (ctx, ctx->buf.buf_w);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= 128) {
+ memcpy (ctx->buf.buf, data, 128);
+ pp_crypto_hash_sha2_512_swap_bytes (ctx->buf.buf_w, 16);
+ pp_crypto_hash_sha2_512_process (ctx, ctx->buf.buf_w);
+
+ data += 128;
+ len -= 128;
+ }
+
+ if (len > 0)
+ memcpy (ctx->buf.buf + left, data, len);
+}
+
+void
+p_crypto_hash_sha2_512_finish (PHashSHA2_512 *ctx)
+{
+ puint64 high, low;
+ pint left, last;
+
+ left = (pint) (ctx->len_low & 0x7F);
+ last = (left < 112) ? (112 - left) : (240 - left);
+
+ low = ctx->len_low << 3;
+ high = ctx->len_high << 3
+ | ctx->len_low >> 61;
+
+ if (last > 0)
+ p_crypto_hash_sha2_512_update (ctx, pp_crypto_hash_sha2_512_pad, (psize) last);
+
+ ctx->buf.buf_w[14] = high;
+ ctx->buf.buf_w[15] = low;
+
+ pp_crypto_hash_sha2_512_swap_bytes (ctx->buf.buf_w, 14);
+ pp_crypto_hash_sha2_512_process (ctx, ctx->buf.buf_w);
+
+ pp_crypto_hash_sha2_512_swap_bytes (ctx->hash, ctx->is384 == FALSE ? 8 : 6);
+}
+
+const puchar *
+p_crypto_hash_sha2_512_digest (PHashSHA2_512 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_sha2_512_free (PHashSHA2_512 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-sha2-512.h b/3rdparty/plibsys/src/pcryptohash-sha2-512.h
new file mode 100644
index 0000000..ce0c2f7
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha2-512.h
@@ -0,0 +1,59 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* SHA2-512 interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHSHA2_512_H
+#define PLIBSYS_HEADER_PCRYPTOHASHSHA2_512_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashSHA2_512_ PHashSHA2_512;
+
+PHashSHA2_512 * p_crypto_hash_sha2_512_new (void);
+void p_crypto_hash_sha2_512_update (PHashSHA2_512 *ctx, const puchar *data, psize len);
+void p_crypto_hash_sha2_512_finish (PHashSHA2_512 *ctx);
+const puchar * p_crypto_hash_sha2_512_digest (PHashSHA2_512 *ctx);
+void p_crypto_hash_sha2_512_reset (PHashSHA2_512 *ctx);
+void p_crypto_hash_sha2_512_free (PHashSHA2_512 *ctx);
+
+PHashSHA2_512 * p_crypto_hash_sha2_384_new (void);
+
+#define p_crypto_hash_sha2_384_update p_crypto_hash_sha2_512_update
+#define p_crypto_hash_sha2_384_finish p_crypto_hash_sha2_512_finish
+#define p_crypto_hash_sha2_384_digest p_crypto_hash_sha2_512_digest
+#define p_crypto_hash_sha2_384_reset p_crypto_hash_sha2_512_reset
+#define p_crypto_hash_sha2_384_free p_crypto_hash_sha2_512_free
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHSHA2_512_H */
diff --git a/3rdparty/plibsys/src/pcryptohash-sha3.c b/3rdparty/plibsys/src/pcryptohash-sha3.c
new file mode 100644
index 0000000..c86545e
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha3.c
@@ -0,0 +1,297 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "pmem.h"
+#include "pcryptohash-sha3.h"
+
+struct PHashSHA3_ {
+ union buf_ {
+ puchar buf[200];
+ puint64 buf_w[25];
+ } buf;
+ puint64 hash[25];
+
+ puint32 len;
+ puint32 block_size;
+};
+
+static const puint64 pp_crypto_hash_sha3_K[] = {
+ 0x0000000000000001ULL, 0x0000000000008082ULL,
+ 0x800000000000808AULL, 0x8000000080008000ULL,
+ 0x000000000000808BULL, 0x0000000080000001ULL,
+ 0x8000000080008081ULL, 0x8000000000008009ULL,
+ 0x000000000000008AULL, 0x0000000000000088ULL,
+ 0x0000000080008009ULL, 0x000000008000000AULL,
+ 0x000000008000808BULL, 0x800000000000008BULL,
+ 0x8000000000008089ULL, 0x8000000000008003ULL,
+ 0x8000000000008002ULL, 0x8000000000000080ULL,
+ 0x000000000000800AULL, 0x800000008000000AULL,
+ 0x8000000080008081ULL, 0x8000000000008080ULL,
+ 0x0000000080000001ULL, 0x8000000080008008ULL
+};
+
+static void pp_crypto_hash_sha3_swap_bytes (puint64 *data, puint words);
+static void pp_crypto_hash_sha3_keccak_theta (PHashSHA3 *ctx);
+static void pp_crypto_hash_sha3_keccak_rho_pi (PHashSHA3 *ctx);
+static void pp_crypto_hash_sha3_keccak_chi (PHashSHA3 *ctx);
+static void pp_crypto_hash_sha3_keccak_permutate (PHashSHA3 *ctx);
+static void pp_crypto_hash_sha3_process (PHashSHA3 *ctx, const puint64 *data);
+static PHashSHA3 * pp_crypto_hash_sha3_new_internal (puint bits);
+
+#define P_SHA3_SHL(val, shift) ((val) << (shift))
+#define P_SHA3_ROTL(val, shift) (P_SHA3_SHL(val, shift) | ((val) >> (64 - (shift))))
+
+static void
+pp_crypto_hash_sha3_swap_bytes (puint64 *data,
+ puint words)
+{
+#ifndef PLIBSYS_IS_BIGENDIAN
+ P_UNUSED (data);
+ P_UNUSED (words);
+#else
+ while (words-- > 0) {
+ *data = PUINT64_TO_LE (*data);
+ ++data;
+ }
+#endif
+}
+
+/* Theta step (see [Keccak Reference, Section 2.3.2]) */
+static void
+pp_crypto_hash_sha3_keccak_theta (PHashSHA3 *ctx)
+{
+ puint i;
+ puint64 C[5], D[5];
+
+ /* Compute the parity of the columns */
+ for (i = 0; i < 5; ++i)
+ C[i] = ctx->hash[i] ^ ctx->hash[i + 5] ^ ctx->hash[i + 10] ^ ctx->hash[i + 15] ^ ctx->hash[i + 20];
+
+ /* Compute the theta effect for a given column */
+ D[0] = P_SHA3_ROTL (C[1], 1) ^ C[4];
+ D[1] = P_SHA3_ROTL (C[2], 1) ^ C[0];
+ D[2] = P_SHA3_ROTL (C[3], 1) ^ C[1];
+ D[3] = P_SHA3_ROTL (C[4], 1) ^ C[2];
+ D[4] = P_SHA3_ROTL (C[0], 1) ^ C[3];
+
+ /* Add the theta effect to the whole column */
+ for (i = 0; i < 5; ++i) {
+ ctx->hash[i] ^= D[i];
+ ctx->hash[i + 5] ^= D[i];
+ ctx->hash[i + 10] ^= D[i];
+ ctx->hash[i + 15] ^= D[i];
+ ctx->hash[i + 20] ^= D[i];
+ }
+}
+
+/* Rho and pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) */
+static void
+pp_crypto_hash_sha3_keccak_rho_pi (PHashSHA3 *ctx)
+{
+ puint64 tmp_A;
+
+ /* Unroll the loop over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23 */
+ tmp_A = ctx->hash[1];
+ ctx->hash[1] = P_SHA3_ROTL (ctx->hash[6], 44);
+ ctx->hash[6] = P_SHA3_ROTL (ctx->hash[9], 20);
+ ctx->hash[9] = P_SHA3_ROTL (ctx->hash[22], 61);
+ ctx->hash[22] = P_SHA3_ROTL (ctx->hash[14], 39);
+ ctx->hash[14] = P_SHA3_ROTL (ctx->hash[20], 18);
+ ctx->hash[20] = P_SHA3_ROTL (ctx->hash[2], 62);
+ ctx->hash[2] = P_SHA3_ROTL (ctx->hash[12], 43);
+ ctx->hash[12] = P_SHA3_ROTL (ctx->hash[13], 25);
+ ctx->hash[13] = P_SHA3_ROTL (ctx->hash[19], 8);
+ ctx->hash[19] = P_SHA3_ROTL (ctx->hash[23], 56);
+ ctx->hash[23] = P_SHA3_ROTL (ctx->hash[15], 41);
+ ctx->hash[15] = P_SHA3_ROTL (ctx->hash[4], 27);
+ ctx->hash[4] = P_SHA3_ROTL (ctx->hash[24], 14);
+ ctx->hash[24] = P_SHA3_ROTL (ctx->hash[21], 2);
+ ctx->hash[21] = P_SHA3_ROTL (ctx->hash[8], 55);
+ ctx->hash[8] = P_SHA3_ROTL (ctx->hash[16], 45);
+ ctx->hash[16] = P_SHA3_ROTL (ctx->hash[5], 36);
+ ctx->hash[5] = P_SHA3_ROTL (ctx->hash[3], 28);
+ ctx->hash[3] = P_SHA3_ROTL (ctx->hash[18], 21);
+ ctx->hash[18] = P_SHA3_ROTL (ctx->hash[17], 15);
+ ctx->hash[17] = P_SHA3_ROTL (ctx->hash[11], 10);
+ ctx->hash[11] = P_SHA3_ROTL (ctx->hash[7], 6);
+ ctx->hash[7] = P_SHA3_ROTL (ctx->hash[10], 3);
+ ctx->hash[10] = P_SHA3_ROTL (tmp_A, 1);
+}
+
+/* Chi step (see [Keccak Reference, Section 2.3.1]) */
+static void
+pp_crypto_hash_sha3_keccak_chi (PHashSHA3 *ctx)
+{
+ puint i;
+ puint64 tmp_A1, tmp_A2;
+
+ for (i = 0; i < 25; i += 5) {
+ tmp_A1 = ctx->hash[i + 0];
+ tmp_A2 = ctx->hash[i + 1];
+
+ ctx->hash[i + 0] ^= ~tmp_A2 & ctx->hash[i + 2];
+ ctx->hash[i + 1] ^= ~ctx->hash[i + 2] & ctx->hash[i + 3];
+ ctx->hash[i + 2] ^= ~ctx->hash[i + 3] & ctx->hash[i + 4];
+ ctx->hash[i + 3] ^= ~ctx->hash[i + 4] & tmp_A1;
+ ctx->hash[i + 4] ^= ~tmp_A1 & tmp_A2;
+ }
+}
+
+static void
+pp_crypto_hash_sha3_keccak_permutate (PHashSHA3 *ctx)
+{
+ puint i;
+
+ for (i = 0; i < 24; ++i) {
+ pp_crypto_hash_sha3_keccak_theta (ctx);
+ pp_crypto_hash_sha3_keccak_rho_pi (ctx);
+ pp_crypto_hash_sha3_keccak_chi (ctx);
+
+ /* Iota step (see [Keccak Reference, Section 2.3.5]) */
+ ctx->hash[0] ^= pp_crypto_hash_sha3_K[i];
+ }
+}
+
+static void
+pp_crypto_hash_sha3_process (PHashSHA3 *ctx,
+ const puint64 *data)
+{
+ puint i;
+ puint qwords = ctx->block_size / 8;
+
+ for (i = 0; i < qwords; ++i)
+ ctx->hash[i] ^= data[i];
+
+ /* Make the Keccak permutation */
+ pp_crypto_hash_sha3_keccak_permutate (ctx);
+}
+
+static PHashSHA3 *
+pp_crypto_hash_sha3_new_internal (puint bits)
+{
+ PHashSHA3 *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashSHA3))) == NULL))
+ return NULL;
+
+ ret->block_size = (1600 - bits * 2) / 8;
+
+ return ret;
+}
+
+void
+p_crypto_hash_sha3_reset (PHashSHA3 *ctx)
+{
+ memset (ctx->buf.buf, 0, 200);
+ memset (ctx->hash, 0, sizeof (ctx->hash));
+
+ ctx->len = 0;
+}
+
+PHashSHA3 *
+p_crypto_hash_sha3_224_new (void)
+{
+ return pp_crypto_hash_sha3_new_internal (224);
+}
+
+PHashSHA3 *
+p_crypto_hash_sha3_256_new (void)
+{
+ return pp_crypto_hash_sha3_new_internal (256);
+}
+
+PHashSHA3 *
+p_crypto_hash_sha3_384_new (void)
+{
+ return pp_crypto_hash_sha3_new_internal (384);
+}
+
+PHashSHA3 *
+p_crypto_hash_sha3_512_new (void)
+{
+ return pp_crypto_hash_sha3_new_internal (512);
+}
+
+void
+p_crypto_hash_sha3_update (PHashSHA3 *ctx,
+ const puchar *data,
+ psize len)
+{
+ puint32 left, to_fill;
+
+ left = ctx->len;
+ to_fill = ctx->block_size - left;
+ ctx->len = (puint32) (((psize) ctx->len + len) % (psize) ctx->block_size);
+
+ if (left && (puint64) len >= to_fill) {
+ memcpy (ctx->buf.buf + left, data, to_fill);
+ pp_crypto_hash_sha3_swap_bytes (ctx->buf.buf_w, ctx->block_size >> 3);
+ pp_crypto_hash_sha3_process (ctx, ctx->buf.buf_w);
+
+ data += to_fill;
+ len -= to_fill;
+ left = 0;
+ }
+
+ while (len >= ctx->block_size) {
+ memcpy (ctx->buf.buf, data, ctx->block_size);
+ pp_crypto_hash_sha3_swap_bytes (ctx->buf.buf_w, ctx->block_size >> 3);
+ pp_crypto_hash_sha3_process (ctx, ctx->buf.buf_w);
+
+ data += ctx->block_size;
+ len -= ctx->block_size;
+ }
+
+ if (len > 0)
+ memcpy (ctx->buf.buf + left, data, len);
+}
+
+void
+p_crypto_hash_sha3_finish (PHashSHA3 *ctx)
+{
+ memset (ctx->buf.buf + ctx->len, 0, ctx->block_size - ctx->len);
+ ctx->buf.buf[ctx->len] |= 0x06;
+ ctx->buf.buf[ctx->block_size - 1] |= 0x80;
+
+ pp_crypto_hash_sha3_swap_bytes (ctx->buf.buf_w, ctx->block_size >> 3);
+ pp_crypto_hash_sha3_process (ctx, ctx->buf.buf_w);
+
+ pp_crypto_hash_sha3_swap_bytes (ctx->hash, (100 - (ctx->block_size >> 2)) >> 3);
+}
+
+const puchar *
+p_crypto_hash_sha3_digest (PHashSHA3 *ctx)
+{
+ return (const puchar *) ctx->hash;
+}
+
+void
+p_crypto_hash_sha3_free (PHashSHA3 *ctx)
+{
+ p_free (ctx);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash-sha3.h b/3rdparty/plibsys/src/pcryptohash-sha3.h
new file mode 100644
index 0000000..ad64e70
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash-sha3.h
@@ -0,0 +1,79 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* SHA-3 (Keccak) interface implementation for #PCryptoHash */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASHSHA3_H
+#define PLIBSYS_HEADER_PCRYPTOHASHSHA3_H
+
+#include "ptypes.h"
+#include "pmacros.h"
+
+P_BEGIN_DECLS
+
+typedef struct PHashSHA3_ PHashSHA3;
+
+void p_crypto_hash_sha3_update (PHashSHA3 *ctx, const puchar *data, psize len);
+void p_crypto_hash_sha3_finish (PHashSHA3 *ctx);
+const puchar * p_crypto_hash_sha3_digest (PHashSHA3 *ctx);
+void p_crypto_hash_sha3_reset (PHashSHA3 *ctx);
+void p_crypto_hash_sha3_free (PHashSHA3 *ctx);
+
+PHashSHA3 * p_crypto_hash_sha3_224_new (void);
+PHashSHA3 * p_crypto_hash_sha3_256_new (void);
+PHashSHA3 * p_crypto_hash_sha3_384_new (void);
+PHashSHA3 * p_crypto_hash_sha3_512_new (void);
+
+#define p_crypto_hash_sha3_224_update p_crypto_hash_sha3_update
+#define p_crypto_hash_sha3_224_finish p_crypto_hash_sha3_finish
+#define p_crypto_hash_sha3_224_digest p_crypto_hash_sha3_digest
+#define p_crypto_hash_sha3_224_reset p_crypto_hash_sha3_reset
+#define p_crypto_hash_sha3_224_free p_crypto_hash_sha3_free
+
+#define p_crypto_hash_sha3_256_update p_crypto_hash_sha3_update
+#define p_crypto_hash_sha3_256_finish p_crypto_hash_sha3_finish
+#define p_crypto_hash_sha3_256_digest p_crypto_hash_sha3_digest
+#define p_crypto_hash_sha3_256_reset p_crypto_hash_sha3_reset
+#define p_crypto_hash_sha3_256_free p_crypto_hash_sha3_free
+
+#define p_crypto_hash_sha3_384_update p_crypto_hash_sha3_update
+#define p_crypto_hash_sha3_384_finish p_crypto_hash_sha3_finish
+#define p_crypto_hash_sha3_384_digest p_crypto_hash_sha3_digest
+#define p_crypto_hash_sha3_384_reset p_crypto_hash_sha3_reset
+#define p_crypto_hash_sha3_384_free p_crypto_hash_sha3_free
+
+#define p_crypto_hash_sha3_512_update p_crypto_hash_sha3_update
+#define p_crypto_hash_sha3_512_finish p_crypto_hash_sha3_finish
+#define p_crypto_hash_sha3_512_digest p_crypto_hash_sha3_digest
+#define p_crypto_hash_sha3_512_reset p_crypto_hash_sha3_reset
+#define p_crypto_hash_sha3_512_free p_crypto_hash_sha3_free
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASHSHA3_H */
diff --git a/3rdparty/plibsys/src/pcryptohash.c b/3rdparty/plibsys/src/pcryptohash.c
new file mode 100644
index 0000000..2ccb6a6
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash.c
@@ -0,0 +1,250 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcryptohash.h"
+#include "pcryptohash-gost3411.h"
+#include "pcryptohash-md5.h"
+#include "pcryptohash-sha1.h"
+#include "pcryptohash-sha2-256.h"
+#include "pcryptohash-sha2-512.h"
+#include "pcryptohash-sha3.h"
+
+#include <string.h>
+
+#define P_HASH_FUNCS(ctx, type) \
+ ctx->create = (void * (*) (void)) p_crypto_hash_##type##_new; \
+ ctx->update = (void (*) (void *, const puchar *, psize)) p_crypto_hash_##type##_update; \
+ ctx->finish = (void (*) (void *)) p_crypto_hash_##type##_finish; \
+ ctx->digest = (const puchar * (*) (void *)) p_crypto_hash_##type##_digest; \
+ ctx->reset = (void (*) (void *)) p_crypto_hash_##type##_reset; \
+ ctx->free = (void (*) (void *)) p_crypto_hash_##type##_free;
+
+struct PCryptoHash_ {
+ PCryptoHashType type;
+ ppointer context;
+ puint hash_len;
+ pboolean closed;
+ ppointer (*create) (void);
+ void (*update) (void *hash, const puchar *data, psize len);
+ void (*finish) (void *hash);
+ const puchar * (*digest) (void *hash);
+ void (*reset) (void *hash);
+ void (*free) (void *hash);
+};
+
+static pchar pp_crypto_hash_hex_str[]= "0123456789abcdef";
+
+static void
+pp_crypto_hash_digest_to_hex (const puchar *digest, puint len, pchar *out);
+
+static void
+pp_crypto_hash_digest_to_hex (const puchar *digest, puint len, pchar *out)
+{
+ puint i;
+
+ for (i = 0; i < len; ++i) {
+ *(out + (i << 1) ) = pp_crypto_hash_hex_str[(digest[i] >> 4) & 0x0F];
+ *(out + (i << 1) + 1) = pp_crypto_hash_hex_str[(digest[i] ) & 0x0F];
+ }
+}
+
+P_LIB_API PCryptoHash *
+p_crypto_hash_new (PCryptoHashType type)
+{
+ PCryptoHash *ret;
+
+ if (P_UNLIKELY (!(type >= P_CRYPTO_HASH_TYPE_MD5 && type <= P_CRYPTO_HASH_TYPE_GOST)))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCryptoHash))) == NULL)) {
+ P_ERROR ("PCryptoHash::p_crypto_hash_new: failed to allocate memory");
+ return NULL;
+ }
+
+ switch (type) {
+ case P_CRYPTO_HASH_TYPE_MD5:
+ P_HASH_FUNCS (ret, md5);
+ ret->hash_len = 16;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA1:
+ P_HASH_FUNCS (ret, sha1);
+ ret->hash_len = 20;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA2_224:
+ P_HASH_FUNCS (ret, sha2_224);
+ ret->hash_len = 28;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA2_256:
+ P_HASH_FUNCS (ret, sha2_256);
+ ret->hash_len = 32;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA2_384:
+ P_HASH_FUNCS (ret, sha2_384);
+ ret->hash_len = 48;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA2_512:
+ P_HASH_FUNCS (ret, sha2_512);
+ ret->hash_len = 64;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA3_224:
+ P_HASH_FUNCS (ret, sha3_224);
+ ret->hash_len = 28;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA3_256:
+ P_HASH_FUNCS (ret, sha3_256);
+ ret->hash_len = 32;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA3_384:
+ P_HASH_FUNCS (ret, sha3_384);
+ ret->hash_len = 48;
+ break;
+ case P_CRYPTO_HASH_TYPE_SHA3_512:
+ P_HASH_FUNCS (ret, sha3_512);
+ ret->hash_len = 64;
+ break;
+ case P_CRYPTO_HASH_TYPE_GOST:
+ P_HASH_FUNCS (ret, gost3411);
+ ret->hash_len = 32;
+ break;
+ }
+
+ ret->type = type;
+ ret->closed = FALSE;
+
+ if (P_UNLIKELY ((ret->context = ret->create ()) == NULL)) {
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_crypto_hash_update (PCryptoHash *hash, const puchar *data, psize len)
+{
+ if (P_UNLIKELY (hash == NULL || data == NULL || len == 0))
+ return;
+
+ if (P_UNLIKELY (hash->closed))
+ return;
+
+ hash->update (hash->context, data, len);
+}
+
+P_LIB_API void
+p_crypto_hash_reset (PCryptoHash *hash)
+{
+ if (P_UNLIKELY (hash == NULL))
+ return;
+
+ hash->reset (hash->context);
+ hash->closed = FALSE;
+}
+
+P_LIB_API pchar *
+p_crypto_hash_get_string (PCryptoHash *hash)
+{
+ pchar *ret;
+ const puchar *digest;
+
+ if (P_UNLIKELY (hash == NULL))
+ return NULL;
+
+ if (!hash->closed) {
+ hash->finish (hash->context);
+ hash->closed = TRUE;
+ }
+
+ if (P_UNLIKELY ((digest = hash->digest (hash->context)) == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (hash->hash_len * 2 + 1)) == NULL))
+ return NULL;
+
+ pp_crypto_hash_digest_to_hex (digest, hash->hash_len, ret);
+
+ return ret;
+}
+
+P_LIB_API void
+p_crypto_hash_get_digest (PCryptoHash *hash, puchar *buf, psize *len)
+{
+ const puchar *digest;
+
+ if (P_UNLIKELY (len == NULL))
+ return;
+
+ if (P_UNLIKELY (hash == NULL || buf == NULL)) {
+ *len = 0;
+ return;
+ }
+
+ if (P_UNLIKELY (hash->hash_len > *len)) {
+ *len = 0;
+ return;
+ }
+
+ if (!hash->closed) {
+ hash->finish (hash->context);
+ hash->closed = TRUE;
+ }
+
+ if (P_UNLIKELY ((digest = hash->digest (hash->context)) == NULL)) {
+ *len = 0;
+ return;
+ }
+
+ memcpy (buf, digest, hash->hash_len);
+ *len = hash->hash_len;
+}
+
+P_LIB_API pssize
+p_crypto_hash_get_length (const PCryptoHash *hash)
+{
+ if (P_UNLIKELY (hash == NULL))
+ return 0;
+
+ return hash->hash_len;
+}
+
+P_LIB_API PCryptoHashType
+p_crypto_hash_get_type (const PCryptoHash *hash)
+{
+ if (P_UNLIKELY (hash == NULL))
+ return (PCryptoHashType) -1;
+
+ return hash->type;
+}
+
+P_LIB_API void
+p_crypto_hash_free (PCryptoHash *hash)
+{
+ if (P_UNLIKELY (hash == NULL))
+ return;
+
+ hash->free (hash->context);
+ p_free (hash);
+}
diff --git a/3rdparty/plibsys/src/pcryptohash.h b/3rdparty/plibsys/src/pcryptohash.h
new file mode 100644
index 0000000..47a8a6c
--- /dev/null
+++ b/3rdparty/plibsys/src/pcryptohash.h
@@ -0,0 +1,188 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pcryptohash.h
+ * @brief Cryptographic hash function
+ * @author Alexander Saprykin
+ *
+ * A cryptographic hash function is an algorithm which performs a transformation
+ * of the income data to a hash value.
+ *
+ * One of the main requirements to all of the cryptographic hashing algorithms
+ * is that any (even a considerably small) change in the input data must lead to
+ * notable changes in the result hash value. It is the so called avalanche
+ * effect. It helps to avoid collisions (the same hash value for different
+ * input arrays).
+ *
+ * The cryptographic hash function is designed to be a one-way so you couldn't
+ * revert the output hash value to the input data back. The length of the
+ * resulting hash is a constant value depending on the algorithm being used.
+ *
+ * A cryptographic hash works with the incoming data using fixed length blocks
+ * so it is possible to feed as many data as required.
+ *
+ * The cryptographic hash module supports the following hash functions:
+ * - MD5;
+ * - SHA-1;
+ * - SHA-2/224;
+ * - SHA-2/256;
+ * - SHA-2/384;
+ * - SHA-2/512;
+ * - SHA-3/224;
+ * - SHA-3/256;
+ * - SHA-3/384;
+ * - SHA-3/512;
+ * - GOST (R 34.11-94).
+ *
+ * Use p_crypto_hash_new() to initialize a new hash context with one of the
+ * mentioned above types. Data for hashing can be added in several chunks using
+ * the p_crypto_hash_update() routine. You can add more chunks as long as the
+ * hash context is open.
+ *
+ * The hash context becomes close in two cases: p_crypto_hash_get_string() or
+ * p_crypto_hash_get_digest() was called. After that you can only get a hash in
+ * a hexidemical string or in a raw representation.
+ *
+ * A hashing algorithm couldn't be changed after the context initialization.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PCRYPTOHASH_H
+#define PLIBSYS_HEADER_PCRYPTOHASH_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Opaque data structure for handling a cryptographic hash context. */
+typedef struct PCryptoHash_ PCryptoHash;
+
+/** Cryptographic hash function types for #PCryptoHash. */
+typedef enum PCryptoHashType_ {
+ P_CRYPTO_HASH_TYPE_MD5 = 0, /**< MD5 hash function. @since 0.0.1 */
+ P_CRYPTO_HASH_TYPE_SHA1 = 1, /**< SHA-1 hash function. @since 0.0.1 */
+ P_CRYPTO_HASH_TYPE_SHA2_224 = 2, /**< SHA-2/224 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA2_256 = 3, /**< SHA-2/256 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA2_384 = 4, /**< SHA-2/384 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA2_512 = 5, /**< SHA-2/512 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA3_224 = 6, /**< SHA-2/224 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA3_256 = 7, /**< SHA-2/256 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA3_384 = 8, /**< SHA-2/384 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_SHA3_512 = 9, /**< SHA-3/512 hash function. @since 0.0.2 */
+ P_CRYPTO_HASH_TYPE_GOST = 10 /**< GOST (R 34.11-94) hash function. @since 0.0.1 */
+} PCryptoHashType;
+
+/**
+ * @brief Initializes a new #PCryptoHash context.
+ * @param type Hash function type to use, can't be changed later.
+ * @return Newly initialized #PCryptoHash context in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PCryptoHash * p_crypto_hash_new (PCryptoHashType type);
+
+/**
+ * @brief Adds a new chunk of data for hashing.
+ * @param hash #PCryptoHash context to add @a data to.
+ * @param data Data to add for hashing.
+ * @param len Data length, in bytes.
+ * @note After calling p_crypto_hash_get_string() or p_crypto_hash_get_digest()
+ * the hash couldn't be updated anymore as it becomes close.
+ * @since 0.0.1
+ */
+P_LIB_API void p_crypto_hash_update (PCryptoHash *hash,
+ const puchar *data,
+ psize len);
+
+/**
+ * @brief Resets a hash state.
+ * @param hash #PCryptoHash context to reset.
+ * @since 0.0.1
+ *
+ * After a reset the hash context becomes open for updating, but all previously
+ * added data will be lost. A hash function type couldn't be changed during or
+ * after the resets.
+ */
+P_LIB_API void p_crypto_hash_reset (PCryptoHash *hash);
+
+/**
+ * @brief Gets a hash in a hexidemical representation.
+ * @param hash #PCryptoHash context to get a string from.
+ * @return NULL-terminated string with the hexidemical representation of a hash
+ * state in case of success, NULL otherwise. The string should be freed with
+ * p_free() after using it.
+ * @note Before returning the string the hash context will be closed for further
+ * updates.
+ * @since 0.0.1
+ */
+P_LIB_API pchar * p_crypto_hash_get_string (PCryptoHash *hash);
+
+/**
+ * @brief Gets a hash in a raw representation.
+ * @param hash #PCryptoHash context to get a digest from.
+ * @param buf Buffer to store the digest with the hash raw representation.
+ * @param[in,out] len Size of @a buf when calling, count of written bytes
+ * after.
+ * @note Before getting the raw digest the hash context will be closed for
+ * further updates.
+ * @since 0.0.1
+ */
+P_LIB_API void p_crypto_hash_get_digest (PCryptoHash *hash,
+ puchar *buf,
+ psize *len);
+
+/**
+ * @brief Gets a hash digest length depending on its type.
+ * @param hash #PCryptoHash context to get the length for.
+ * @return Length (in bytes) of the given hash depending on its type in case of
+ * success, -1 otherwise.
+ * @note This length doesn't match a string hash representation.
+ * @since 0.0.1
+ */
+P_LIB_API pssize p_crypto_hash_get_length (const PCryptoHash *hash);
+
+/**
+ * @brief Gets a hash function type.
+ * @param hash #PCryptoHash context to get the type for.
+ * @return Hash function type used in the given context.
+ * @since 0.0.1
+ */
+P_LIB_API PCryptoHashType p_crypto_hash_get_type (const PCryptoHash *hash);
+
+/**
+ * @brief Frees a previously initialized hash context.
+ * @param hash #PCryptoHash context to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_crypto_hash_free (PCryptoHash *hash);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PCRYPTOHASH_H */
diff --git a/3rdparty/plibsys/src/pdir-none.c b/3rdparty/plibsys/src/pdir-none.c
new file mode 100644
index 0000000..eaaa8b9
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir-none.c
@@ -0,0 +1,124 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pdir.h"
+
+#include <stdlib.h>
+
+struct PDir_ {
+ pint hdl;
+};
+
+P_LIB_API PDir *
+p_dir_new (const pchar *path,
+ PError **error)
+{
+ P_UNUSED (path);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_IMPLEMENTED,
+ 0,
+ "No directory implementation");
+
+ return NULL;
+}
+
+P_LIB_API pboolean
+p_dir_create (const pchar *path,
+ pint mode,
+ PError **error)
+{
+ P_UNUSED (path);
+ P_UNUSED (mode);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_IMPLEMENTED,
+ 0,
+ "No directory implementation");
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_dir_remove (const pchar *path,
+ PError **error)
+{
+ P_UNUSED (path);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_IMPLEMENTED,
+ 0,
+ "No directory implementation");
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_dir_is_exists (const pchar *path)
+{
+ P_UNUSED (path);
+ return FALSE;
+}
+
+P_LIB_API pchar *
+p_dir_get_path (const PDir *dir)
+{
+ P_UNUSED (dir);
+ return NULL;
+}
+
+P_LIB_API PDirEntry *
+p_dir_get_next_entry (PDir *dir,
+ PError **error)
+{
+ P_UNUSED (dir);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_IMPLEMENTED,
+ 0,
+ "No directory implementation");
+
+ return NULL;
+}
+
+P_LIB_API pboolean
+p_dir_rewind (PDir *dir,
+ PError **error)
+{
+ P_UNUSED (dir);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_IMPLEMENTED,
+ 0,
+ "No directory implementation");
+
+ return FALSE;
+}
+
+P_LIB_API void
+p_dir_free (PDir *dir)
+{
+ P_UNUSED (dir);
+}
diff --git a/3rdparty/plibsys/src/pdir-os2.c b/3rdparty/plibsys/src/pdir-os2.c
new file mode 100644
index 0000000..8869329
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir-os2.c
@@ -0,0 +1,381 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pdir.h"
+#include "perror.h"
+#include "pmem.h"
+#include "pstring.h"
+#include "perror-private.h"
+
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#include <os2.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+struct PDir_ {
+ FILEFINDBUF3 find_data;
+ HDIR search_handle;
+ pboolean cached;
+ pchar path[CCHMAXPATH];
+ pchar *orig_path;
+};
+
+P_LIB_API PDir *
+p_dir_new (const pchar *path,
+ PError **error)
+{
+ PDir *ret;
+ pchar *pathp;
+ pchar *adj_path;
+ pint path_len;
+ APIRET ulrc;
+ ULONG find_count;
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDir))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory structure");
+ return NULL;
+ }
+
+ adj_path = NULL;
+ path_len = strlen (path);
+
+ if (P_UNLIKELY (path[path_len - 1] == '\\' || path[path_len - 1] == '/') && path_len > 1) {
+ while ((path[path_len - 1] == '\\' || path[path_len - 1] == '/') && path_len > 1)
+ --path_len;
+
+ if (P_UNLIKELY ((adj_path = p_malloc0 (path_len + 1)) == NULL)) {
+ p_free (ret);
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory path");
+ return NULL;
+ }
+
+ memcpy (adj_path, path, path_len);
+
+ adj_path[path_len] = '\0';
+ ret->orig_path = p_strdup (path);
+ path = (const pchar *) adj_path;
+ }
+
+ ret->search_handle = HDIR_CREATE;
+
+ ulrc = DosQueryPathInfo ((PSZ) path, FIL_QUERYFULLNAME, ret->path, sizeof (ret->path) - 2);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosQueryPathInfo() to get directory path");
+
+ if (P_UNLIKELY (adj_path != NULL)) {
+ p_free (adj_path);
+ p_free (ret->orig_path);
+ }
+
+ p_free (ret);
+ return NULL;
+ }
+
+ /* Append the search pattern "\\*\0" to the directory name */
+ pathp = strchr (ret->path, '\0');
+
+ if (ret->path < pathp && *(pathp - 1) != '\\' && *(pathp - 1) != ':')
+ *pathp++ = '\\';
+
+ *pathp++ = '*';
+ *pathp = '\0';
+
+ find_count = 1;
+
+ /* Open directory stream and retrieve the first entry */
+ ulrc = DosFindFirst (ret->path,
+ &ret->search_handle,
+ FILE_NORMAL | FILE_DIRECTORY,
+ &ret->find_data,
+ sizeof (ret->find_data),
+ &find_count,
+ FIL_STANDARD);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR && ulrc != ERROR_NO_MORE_FILES)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosFindFirst() to open directory stream");
+
+ if (P_UNLIKELY (adj_path != NULL)) {
+ p_free (adj_path);
+ p_free (ret->orig_path);
+ }
+
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->cached = TRUE;
+
+ if (P_UNLIKELY (adj_path != NULL))
+ p_free (adj_path);
+ else
+ ret->orig_path = p_strdup (path);
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_create (const pchar *path,
+ pint mode,
+ PError **error)
+{
+ APIRET ulrc;
+
+ P_UNUSED (mode);
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (p_dir_is_exists (path))
+ return TRUE;
+
+ if (P_UNLIKELY ((ulrc = DosCreateDir ((PSZ) path, NULL)) != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosCreateDir() to create directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_remove (const pchar *path,
+ PError **error)
+{
+ APIRET ulrc;
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (!p_dir_is_exists (path)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_EXISTS,
+ 0,
+ "Specified directory doesn't exist");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((ulrc = DosDeleteDir ((PSZ) path)) != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosDeleteDir() to remove directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_is_exists (const pchar *path)
+{
+ FILESTATUS3 status;
+
+ if (P_UNLIKELY (path == NULL))
+ return FALSE;
+
+ if (DosQueryPathInfo ((PSZ) path, FIL_STANDARD, (PVOID) &status, sizeof (status)) != NO_ERROR)
+ return FALSE;
+
+ return (status.attrFile & FILE_DIRECTORY) != 0;
+}
+
+P_LIB_API pchar *
+p_dir_get_path (const PDir *dir)
+{
+ if (P_UNLIKELY (dir == NULL))
+ return NULL;
+
+ return p_strdup (dir->orig_path);
+}
+
+P_LIB_API PDirEntry *
+p_dir_get_next_entry (PDir *dir,
+ PError **error)
+{
+ PDirEntry *ret;
+ APIRET ulrc;
+ ULONG find_count;
+
+ if (P_UNLIKELY (dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (dir->cached == TRUE) {
+ dir->cached = FALSE;
+
+ /* Opened directory is empty */
+ if (P_UNLIKELY (dir->search_handle == HDIR_CREATE)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_MORE,
+ (pint) ERROR_NO_MORE_FILES,
+ "Directory is empty to get the next entry");
+ return NULL;
+ }
+ } else {
+ if (P_UNLIKELY (dir->search_handle == HDIR_CREATE)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Not a valid (or closed) directory stream");
+ return NULL;
+ }
+
+ find_count = 1;
+
+ ulrc = DosFindNext (dir->search_handle,
+ (PVOID) &dir->find_data,
+ sizeof (dir->find_data),
+ &find_count);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosFindNext() to read directory stream");
+ DosFindClose (dir->search_handle);
+ dir->search_handle = HDIR_CREATE;
+ return NULL;
+ }
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDirEntry))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory entry");
+ return NULL;
+ }
+
+ ret->name = p_strdup (dir->find_data.achName);
+
+ if ((dir->find_data.attrFile & FILE_DIRECTORY) != 0)
+ ret->type = P_DIR_ENTRY_TYPE_DIR;
+ else
+ ret->type = P_DIR_ENTRY_TYPE_FILE;
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_rewind (PDir *dir,
+ PError **error)
+{
+ APIRET ulrc;
+ ULONG find_count;
+
+ if (P_UNLIKELY (dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (dir->search_handle != HDIR_CREATE) {
+ if (P_UNLIKELY ((ulrc = DosFindClose (dir->search_handle)) != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosFindClose() to close directory stream");
+ return FALSE;
+ }
+
+ dir->search_handle = HDIR_CREATE;
+ }
+
+ find_count = 1;
+
+ ulrc = DosFindFirst (dir->path,
+ &dir->search_handle,
+ FILE_NORMAL | FILE_DIRECTORY,
+ &dir->find_data,
+ sizeof (dir->find_data),
+ &find_count,
+ FIL_STANDARD);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR && ulrc != ERROR_NO_MORE_FILES)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosFindFirst() to open directory stream");
+ dir->cached = FALSE;
+ return FALSE;
+ } else {
+ dir->cached = TRUE;
+ return TRUE;
+ }
+}
+
+P_LIB_API void
+p_dir_free (PDir *dir)
+{
+ if (dir == NULL)
+ return;
+
+ if (P_LIKELY (dir->search_handle != HDIR_CREATE)) {
+ if (P_UNLIKELY (DosFindClose (dir->search_handle) != NO_ERROR))
+ P_ERROR ("PDir::p_dir_free: DosFindClose() failed");
+ }
+
+ p_free (dir->orig_path);
+ p_free (dir);
+}
diff --git a/3rdparty/plibsys/src/pdir-posix.c b/3rdparty/plibsys/src/pdir-posix.c
new file mode 100644
index 0000000..22b7863
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir-posix.c
@@ -0,0 +1,378 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pdir.h"
+#include "perror.h"
+#include "pfile.h"
+#include "pmem.h"
+#include "pstring.h"
+#include "perror-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#if defined (__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 24)
+# define P_DIR_NON_REENTRANT 1
+# elif defined (P_OS_SOLARIS) || defined (P_OS_QNX6) || defined (P_OS_UNIXWARE) || \
+ defined (P_OS_SCO) || defined (P_OS_IRIX) || defined (P_OS_HAIKU)
+# define P_DIR_NEED_BUF_ALLOC 1
+#endif
+
+#ifdef P_DIR_NEED_BUF_ALLOC
+# if defined (P_OS_SCO)
+# define P_DIR_NEED_SIMPLE_R 1
+# endif
+#else
+# if defined (P_OS_BEOS) || defined (P_OS_AMIGA)
+# define P_DIR_NON_REENTRANT 1
+# endif
+#endif
+
+struct PDir_ {
+ DIR * dir;
+ struct dirent *dir_result;
+ pchar *path;
+ pchar *orig_path;
+};
+
+P_LIB_API PDir *
+p_dir_new (const pchar *path,
+ PError **error)
+{
+ PDir *ret;
+ DIR *dir;
+ pchar *pathp;
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((dir = opendir (path)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call opendir() to open directory stream");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDir))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory structure");
+ closedir (dir);
+ return NULL;
+ }
+
+ ret->dir = dir;
+ ret->path = p_strdup (path);
+ ret->orig_path = p_strdup (path);
+
+ pathp = ret->path + strlen (ret->path) - 1;
+
+ if (*pathp == '/' || *pathp == '\\')
+ *pathp = '\0';
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_create (const pchar *path,
+ pint mode,
+ PError **error)
+{
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (p_dir_is_exists (path))
+ return TRUE;
+
+ if (P_UNLIKELY (mkdir (path, (mode_t) mode) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call mkdir() to create directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_remove (const pchar *path,
+ PError **error)
+{
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (!p_dir_is_exists (path)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_EXISTS,
+ 0,
+ "Specified directory doesn't exist");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (rmdir (path) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call rmdir() to remove directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_is_exists (const pchar *path)
+{
+ struct stat sb;
+
+ if (P_UNLIKELY (path == NULL))
+ return FALSE;
+
+ return (stat (path, &sb) == 0 && S_ISDIR (sb.st_mode)) ? TRUE : FALSE;
+}
+
+P_LIB_API pchar *
+p_dir_get_path (const PDir *dir)
+{
+ if (P_UNLIKELY (dir == NULL))
+ return NULL;
+
+ return p_strdup (dir->orig_path);
+}
+
+P_LIB_API PDirEntry *
+p_dir_get_next_entry (PDir *dir,
+ PError **error)
+{
+ PDirEntry *ret;
+#ifdef P_DIR_NEED_BUF_ALLOC
+ struct dirent *dirent_st;
+#elif !defined (P_DIR_NON_REENTRANT)
+ struct dirent dirent_st;
+#endif
+ struct stat sb;
+ pchar *entry_path;
+ psize path_len;
+#ifdef P_DIR_NEED_BUF_ALLOC
+ pint name_max;
+#endif
+
+ if (P_UNLIKELY (dir == NULL || dir->dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+#ifdef P_DIR_NEED_BUF_ALLOC
+# if defined (P_OS_SOLARIS)
+ name_max = (pint) (FILENAME_MAX);
+# elif defined (P_OS_SCO) || defined (P_OS_IRIX)
+ name_max = (pint) pathconf (dir->orig_path, _PC_NAME_MAX);
+
+ if (name_max == -1) {
+ if (p_error_get_last_system () == 0)
+ name_max = _POSIX_PATH_MAX;
+ else {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to get NAME_MAX using pathconf()");
+ return NULL;
+ }
+ }
+# elif defined (P_OS_QNX6) || defined (P_OS_UNIXWARE) || defined (P_OS_HAIKU)
+ name_max = (pint) (NAME_MAX);
+# endif
+
+ if (P_UNLIKELY ((dirent_st = p_malloc0 (sizeof (struct dirent) + name_max + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for internal directory entry");
+ return NULL;
+ }
+
+# ifdef P_DIR_NEED_SIMPLE_R
+ p_error_set_last_system (0);
+
+ if ((dir->dir_result = readdir_r (dir->dir, dirent_st)) == NULL) {
+ if (P_UNLIKELY (p_error_get_last_system () != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call readdir_r() to read directory stream");
+ p_free (dirent_st);
+ return NULL;
+ }
+ }
+# else
+ if (P_UNLIKELY (readdir_r (dir->dir, dirent_st, &dir->dir_result) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call readdir_r() to read directory stream");
+ p_free (dirent_st);
+ return NULL;
+ }
+# endif
+#else
+# ifdef P_DIR_NON_REENTRANT
+ p_error_set_last_system (0);
+
+ if ((dir->dir_result = readdir (dir->dir)) == NULL) {
+ if (P_UNLIKELY (p_error_get_last_system () != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call readdir() to read directory stream");
+ return NULL;
+ }
+ }
+# else
+ if (P_UNLIKELY (readdir_r (dir->dir, &dirent_st, &dir->dir_result) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call readdir_r() to read directory stream");
+ return NULL;
+ }
+# endif
+#endif
+
+ if (dir->dir_result == NULL) {
+#ifdef P_DIR_NEED_BUF_ALLOC
+ p_free (dirent_st);
+#endif
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDirEntry))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory entry");
+#ifdef P_DIR_NEED_BUF_ALLOC
+ p_free (dirent_st);
+#endif
+ return NULL;
+ }
+
+#ifdef P_DIR_NEED_BUF_ALLOC
+ ret->name = p_strdup (dirent_st->d_name);
+ p_free (dirent_st);
+#else
+# ifdef P_DIR_NON_REENTRANT
+ ret->name = p_strdup (dir->dir_result->d_name);
+# else
+ ret->name = p_strdup (dirent_st.d_name);
+# endif
+#endif
+
+ path_len = strlen (dir->path);
+
+ if (P_UNLIKELY ((entry_path = p_malloc0 (path_len + strlen (ret->name) + 2)) == NULL)) {
+ P_WARNING ("PDir::p_dir_get_next_entry: failed to allocate memory for stat()");
+ ret->type = P_DIR_ENTRY_TYPE_OTHER;
+ return ret;
+ }
+
+ strcat (entry_path, dir->path);
+ *(entry_path + path_len) = '/';
+ strcat (entry_path + path_len + 1, ret->name);
+
+ if (P_UNLIKELY (stat (entry_path, &sb) != 0)) {
+ P_WARNING ("PDir::p_dir_get_next_entry: stat() failed");
+ ret->type = P_DIR_ENTRY_TYPE_OTHER;
+ p_free (entry_path);
+ return ret;
+ }
+
+ p_free (entry_path);
+
+ if (S_ISDIR (sb.st_mode))
+ ret->type = P_DIR_ENTRY_TYPE_DIR;
+ else if (S_ISREG (sb.st_mode))
+ ret->type = P_DIR_ENTRY_TYPE_FILE;
+ else
+ ret->type = P_DIR_ENTRY_TYPE_OTHER;
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_rewind (PDir *dir,
+ PError **error)
+{
+ if (P_UNLIKELY (dir == NULL || dir->dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ rewinddir (dir->dir);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_dir_free (PDir *dir)
+{
+ if (P_UNLIKELY (dir == NULL))
+ return;
+
+ if (P_LIKELY (dir->dir != NULL)) {
+ if (P_UNLIKELY (closedir (dir->dir) != 0))
+ P_ERROR ("PDir::p_dir_free: closedir() failed");
+ }
+
+ p_free (dir->path);
+ p_free (dir->orig_path);
+ p_free (dir);
+}
diff --git a/3rdparty/plibsys/src/pdir-win.c b/3rdparty/plibsys/src/pdir-win.c
new file mode 100644
index 0000000..8c6df15
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir-win.c
@@ -0,0 +1,291 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pdir.h"
+#include "perror.h"
+#include "pmem.h"
+#include "pstring.h"
+#include "perror-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+struct PDir_ {
+ WIN32_FIND_DATAA find_data;
+ HANDLE search_handle;
+ pboolean cached;
+ pchar path[MAX_PATH + 3];
+ pchar *orig_path;
+};
+
+P_LIB_API PDir *
+p_dir_new (const pchar *path,
+ PError **error)
+{
+ PDir *ret;
+ pchar *pathp;
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDir))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory structure");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (!GetFullPathNameA (path, MAX_PATH, ret->path, NULL))) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call GetFullPathNameA() to get directory path");
+ p_free (ret);
+ return NULL;
+ }
+
+ /* Append the search pattern "\\*\0" to the directory name */
+ pathp = strchr (ret->path, '\0');
+
+ if (ret->path < pathp && *(pathp - 1) != '\\' && *(pathp - 1) != ':')
+ *pathp++ = '\\';
+
+ *pathp++ = '*';
+ *pathp = '\0';
+
+ /* Open directory stream and retrieve the first entry */
+ ret->search_handle = FindFirstFileA (ret->path, &ret->find_data);
+
+ if (P_UNLIKELY (ret->search_handle == INVALID_HANDLE_VALUE)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call FindFirstFileA() to open directory stream");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->cached = TRUE;
+ ret->orig_path = p_strdup (path);
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_create (const pchar *path,
+ pint mode,
+ PError **error)
+{
+ P_UNUSED (mode);
+
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (p_dir_is_exists (path))
+ return TRUE;
+
+ if (P_UNLIKELY (CreateDirectoryA (path, NULL) == 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call CreateDirectoryA() to create directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_remove (const pchar *path,
+ PError **error)
+{
+ if (P_UNLIKELY (path == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (!p_dir_is_exists (path)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_EXISTS,
+ 0,
+ "Specified directory doesn't exist");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (RemoveDirectoryA (path) == 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call RemoveDirectoryA() to remove directory");
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_dir_is_exists (const pchar *path)
+{
+ DWORD dwAttrs;
+
+ if (P_UNLIKELY (path == NULL))
+ return FALSE;
+
+ dwAttrs = GetFileAttributesA (path);
+
+ return (dwAttrs != INVALID_FILE_ATTRIBUTES) && (dwAttrs & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+P_LIB_API pchar *
+p_dir_get_path (const PDir *dir)
+{
+ if (P_UNLIKELY (dir == NULL))
+ return NULL;
+
+ return p_strdup (dir->orig_path);
+}
+
+P_LIB_API PDirEntry *
+p_dir_get_next_entry (PDir *dir,
+ PError **error)
+{
+ PDirEntry *ret;
+ DWORD dwAttrs;
+
+ if (P_UNLIKELY (dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (dir->cached == TRUE)
+ dir->cached = FALSE;
+ else {
+ if (P_UNLIKELY (dir->search_handle == INVALID_HANDLE_VALUE)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Not a valid (or closed) directory stream");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (!FindNextFileA (dir->search_handle, &dir->find_data))) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call FindNextFileA() to read directory stream");
+ FindClose (dir->search_handle);
+ dir->search_handle = INVALID_HANDLE_VALUE;
+ return NULL;
+ }
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDirEntry))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for directory entry");
+ return NULL;
+ }
+
+ ret->name = p_strdup (dir->find_data.cFileName);
+
+ dwAttrs = dir->find_data.dwFileAttributes;
+
+ if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY)
+ ret->type = P_DIR_ENTRY_TYPE_DIR;
+ else if (dwAttrs & FILE_ATTRIBUTE_DEVICE)
+ ret->type = P_DIR_ENTRY_TYPE_OTHER;
+ else
+ ret->type = P_DIR_ENTRY_TYPE_FILE;
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_dir_rewind (PDir *dir,
+ PError **error)
+{
+ if (P_UNLIKELY (dir == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (dir->search_handle != INVALID_HANDLE_VALUE) {
+ if (P_UNLIKELY (FindClose (dir->search_handle) == 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call FindClose() to close directory stream");
+ return FALSE;
+ }
+ }
+
+ dir->search_handle = FindFirstFileA (dir->path, &dir->find_data);
+
+ if (P_UNLIKELY (dir->search_handle == INVALID_HANDLE_VALUE)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call FindFirstFileA() to open directory stream");
+ dir->cached = FALSE;
+ return FALSE;
+ } else {
+ dir->cached = TRUE;
+ return TRUE;
+ }
+}
+
+P_LIB_API void
+p_dir_free (PDir *dir)
+{
+ if (dir == NULL)
+ return;
+
+ if (P_LIKELY (dir->search_handle != INVALID_HANDLE_VALUE)) {
+ if (P_UNLIKELY (!FindClose (dir->search_handle)))
+ P_ERROR ("PDir::p_dir_free: FindClose() failed");
+ }
+
+ p_free (dir->orig_path);
+ p_free (dir);
+}
diff --git a/3rdparty/plibsys/src/pdir.c b/3rdparty/plibsys/src/pdir.c
new file mode 100644
index 0000000..4166cf7
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir.c
@@ -0,0 +1,37 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pdir.h"
+
+P_LIB_API void
+p_dir_entry_free (PDirEntry *entry)
+{
+ if (P_UNLIKELY (entry == NULL))
+ return;
+
+ p_free (entry->name);
+ p_free (entry);
+}
diff --git a/3rdparty/plibsys/src/pdir.h b/3rdparty/plibsys/src/pdir.h
new file mode 100644
index 0000000..9438a34
--- /dev/null
+++ b/3rdparty/plibsys/src/pdir.h
@@ -0,0 +1,177 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pdir.h
+ * @brief Filesystem interface
+ * @author Alexander Saprykin
+ *
+ * A traditional filesystem can be presented as a combination of directories and
+ * files within a defined hierarchy. A directory contains the so called entries:
+ * files and other directories. #PDir allows to iterate through these entries
+ * without reading their contents, thus building a filesystem hierarchy tree.
+ *
+ * Think of this module as an interface to the well-known `dirent` API.
+ *
+ * First you need to open a directory for iterating through its content entries
+ * using p_dir_new(). After that every next entry inside the directory can be
+ * read with the p_dir_get_next_entry() call until it returns NULL (though it's
+ * better to check an error code to be sure no error occurred).
+ *
+ * Also some directory manipulation routines are provided to create, remove and
+ * check existance.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PDIR_H
+#define PLIBSYS_HEADER_PDIR_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Directory opaque data structure. */
+typedef struct PDir_ PDir;
+
+/** Directory entry types. */
+typedef enum PDirEntryType_ {
+ P_DIR_ENTRY_TYPE_DIR = 1, /**< Directory. */
+ P_DIR_ENTRY_TYPE_FILE = 2, /**< File. */
+ P_DIR_ENTRY_TYPE_OTHER = 3 /**< Other. */
+} PDirEntryType;
+
+/** Structure with directory entry information. */
+typedef struct PDirEntry_ {
+ char *name; /**< Name. */
+ PDirEntryType type; /**< Type. */
+} PDirEntry;
+
+/**
+ * @brief Creates a new #PDir object.
+ * @param path Directory path.
+ * @return Pointer to a newly created #PDir object in case of success, NULL
+ * otherwise.
+ * @param[out] error Error report object, NULL to ignore.
+ * @since 0.0.1
+ * @note If you want to create a new directory on a filesystem, use
+ * p_dir_create() instead.
+ */
+P_LIB_API PDir * p_dir_new (const pchar *path,
+ PError **error);
+
+/**
+ * @brief Creates a new directory on a filesystem.
+ * @param path Directory path.
+ * @param mode Directory permissions to use, ignored on Windows.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @note Call returns TRUE if the directory @a path is already exists.
+ * @note On OpenVMS operating system it creates intermediate directories as
+ * well.
+ */
+P_LIB_API pboolean p_dir_create (const pchar *path,
+ pint mode,
+ PError **error);
+
+/**
+ * @brief Removes an empty directory.
+ * @param path Directory path to remove.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * The directory @a path should be empty to be removed successfully.
+ */
+P_LIB_API pboolean p_dir_remove (const pchar *path,
+ PError **error);
+
+/**
+ * @brief Checks whether a directory exists or not.
+ * @param path Directory path.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_dir_is_exists (const pchar *path);
+
+/**
+ * @brief Gets the original directory path used to create a #PDir object.
+ * @param dir #PDir object to retrieve the path from.
+ * @return The directory path in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * Caller takes ownership of the returned string. Use p_free() to free memory
+ * after usage.
+ */
+P_LIB_API pchar * p_dir_get_path (const PDir *dir);
+
+/**
+ * @brief Gets the next directory entry info.
+ * @param dir Directory to get the next entry from.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Info for the next entry in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * Caller takes ownership of the returned object. Use p_dir_entry_free() to free
+ * memory of the directory entry after usage.
+ *
+ * An error is set only if it is occurred. You should check the @a error object
+ * for #P_ERROR_IO_NO_MORE code.
+ */
+P_LIB_API PDirEntry * p_dir_get_next_entry (PDir *dir,
+ PError **error);
+
+/**
+ * @brief Resets a directory entry pointer.
+ * @param dir Directory to reset the entry pointer.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_dir_rewind (PDir *dir,
+ PError **error);
+
+/**
+ * @brief Frees #PDirEntry object.
+ * @param entry #PDirEntry to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_dir_entry_free (PDirEntry *entry);
+
+/**
+ * @brief Frees #PDir object.
+ * @param dir #PDir to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_dir_free (PDir *dir);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PDIR_H */
diff --git a/3rdparty/plibsys/src/perror-private.h b/3rdparty/plibsys/src/perror-private.h
new file mode 100644
index 0000000..b108583
--- /dev/null
+++ b/3rdparty/plibsys/src/perror-private.h
@@ -0,0 +1,67 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PERROR_PRIVATE_H
+#define PLIBSYS_HEADER_PERROR_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+#include "perrortypes.h"
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Gets an IO error code from a system error code.
+ * @param err_code System error code.
+ * @return IO error code.
+ */
+PErrorIO p_error_get_io_from_system (pint err_code);
+
+/**
+ * @brief Gets an IO error code from the last call result.
+ * @return IO error code.
+ */
+PErrorIO p_error_get_last_io (void);
+
+/**
+ * @brief Gets an IPC error code from a system error code
+ * @param err_code System error code.
+ * @return IPC error code.
+ */
+PErrorIPC p_error_get_ipc_from_system (pint err_code);
+
+/**
+ * @brief Gets an IPC error code from the last call result.
+ * @return IPC error code.
+ */
+PErrorIPC p_error_get_last_ipc (void);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PERROR_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/perror.c b/3rdparty/plibsys/src/perror.c
new file mode 100644
index 0000000..c26dfa1
--- /dev/null
+++ b/3rdparty/plibsys/src/perror.c
@@ -0,0 +1,878 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "pstring.h"
+#include "perror-private.h"
+
+#ifndef P_OS_WIN
+# if defined (P_OS_OS2)
+# define INCL_DOSERRORS
+# include <os2.h>
+# include <sys/socket.h>
+# endif
+# include <errno.h>
+#endif
+
+struct PError_ {
+ pint code;
+ pint native_code;
+ pchar *message;
+};
+
+PErrorIO
+p_error_get_io_from_system (pint err_code)
+{
+ switch (err_code) {
+ case 0:
+ return P_ERROR_IO_NONE;
+#if defined (P_OS_WIN)
+# ifdef WSAEADDRINUSE
+ case WSAEADDRINUSE:
+ return P_ERROR_IO_ADDRESS_IN_USE;
+# endif
+# ifdef WSAEWOULDBLOCK
+ case WSAEWOULDBLOCK:
+ return P_ERROR_IO_WOULD_BLOCK;
+# endif
+# ifdef WSAEACCES
+ case WSAEACCES:
+ return P_ERROR_IO_ACCESS_DENIED;
+# endif
+# ifdef WSA_INVALID_HANDLE
+ case WSA_INVALID_HANDLE:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef WSA_INVALID_PARAMETER
+ case WSA_INVALID_PARAMETER:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef WSAEBADF
+ case WSAEBADF:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef WSAENOTSOCK
+ case WSAENOTSOCK:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef WSAEINVAL
+ case WSAEINVAL:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef WSAESOCKTNOSUPPORT
+ case WSAESOCKTNOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef WSAEOPNOTSUPP
+ case WSAEOPNOTSUPP:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef WSAEPFNOSUPPORT
+ case WSAEPFNOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef WSAEAFNOSUPPORT
+ case WSAEAFNOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef WSAEPROTONOSUPPORT
+ case WSAEPROTONOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef WSAECANCELLED
+ case WSAECANCELLED:
+ return P_ERROR_IO_ABORTED;
+# endif
+# ifdef ERROR_ALREADY_EXISTS
+ case ERROR_ALREADY_EXISTS:
+ return P_ERROR_IO_EXISTS;
+# endif
+# ifdef ERROR_FILE_NOT_FOUND
+ case ERROR_FILE_NOT_FOUND:
+ return P_ERROR_IO_NOT_EXISTS;
+# endif
+# ifdef ERROR_NO_MORE_FILES
+ case ERROR_NO_MORE_FILES:
+ return P_ERROR_IO_NO_MORE;
+# endif
+# ifdef ERROR_ACCESS_DENIED
+ case ERROR_ACCESS_DENIED:
+ return P_ERROR_IO_ACCESS_DENIED;
+# endif
+# ifdef ERROR_OUTOFMEMORY
+ case ERROR_OUTOFMEMORY:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+# ifdef ERROR_NOT_ENOUGH_MEMORY
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+# ifdef ERROR_INVALID_HANDLE
+# if !defined(WSA_INVALID_HANDLE) || (ERROR_INVALID_HANDLE != WSA_INVALID_HANDLE)
+ case ERROR_INVALID_HANDLE:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# endif
+# ifdef ERROR_INVALID_PARAMETER
+# if !defined(WSA_INVALID_PARAMETER) || (ERROR_INVALID_PARAMETER != WSA_INVALID_PARAMETER)
+ case ERROR_INVALID_PARAMETER:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# endif
+# ifdef ERROR_NOT_SUPPORTED
+ case ERROR_NOT_SUPPORTED:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+#elif defined (P_OS_OS2)
+# ifdef ERROR_FILE_NOT_FOUND
+ case ERROR_FILE_NOT_FOUND:
+ return P_ERROR_IO_NOT_EXISTS;
+# endif
+# ifdef ERROR_PATH_NOT_FOUND
+ case ERROR_PATH_NOT_FOUND:
+ return P_ERROR_IO_NOT_EXISTS;
+# endif
+# ifdef ERROR_TOO_MANY_OPEN_FILES
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+# ifdef ERROR_NOT_ENOUGH_MEMORY
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+# ifdef ERROR_ACCESS_DENIED
+ case ERROR_ACCESS_DENIED:
+ return P_ERROR_IO_ACCESS_DENIED;
+# endif
+# ifdef ERROR_INVALID_HANDLE
+ case ERROR_INVALID_HANDLE:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_INVALID_PARAMETER
+ case ERROR_INVALID_PARAMETER:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_INVALID_ADDRESS
+ case ERROR_INVALID_ADDRESS:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_NO_MORE_FILES
+ case ERROR_NO_MORE_FILES:
+ return P_ERROR_IO_NO_MORE;
+# endif
+# ifdef ERROR_NOT_SUPPORTED
+ case ERROR_NOT_SUPPORTED:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+# ifdef ERROR_FILE_EXISTS
+ case ERROR_FILE_EXISTS:
+ return P_ERROR_IO_EXISTS;
+# endif
+#else /* !P_OS_WIN && !P_OS_OS2 */
+# ifdef EACCES
+ case EACCES:
+ return P_ERROR_IO_ACCESS_DENIED;
+# endif
+
+# ifdef EPERM
+ case EPERM:
+ return P_ERROR_IO_ACCESS_DENIED;
+# endif
+
+# ifdef ENOMEM
+ case ENOMEM:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef ENOSR
+ case ENOSR:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef ENOBUFS
+ case ENOBUFS:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef ENFILE
+ case ENFILE:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef ENOSPC
+ case ENOSPC:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef EMFILE
+ case EMFILE:
+ return P_ERROR_IO_NO_RESOURCES;
+# endif
+
+# ifdef EINVAL
+ case EINVAL:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+
+# ifdef EBADF
+ case EBADF:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+
+# ifdef ENOTSOCK
+ case ENOTSOCK:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+
+# ifdef EFAULT
+ case EFAULT:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+
+# ifdef EPROTOTYPE
+ case EPROTOTYPE:
+ return P_ERROR_IO_INVALID_ARGUMENT;
+# endif
+
+ /* On Linux these errors can have same codes */
+# if defined(ENOTSUP) && (!defined(EOPNOTSUPP) || ENOTSUP != EOPNOTSUPP)
+ case ENOTSUP:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+
+# ifdef ENOPROTOOPT
+ case ENOPROTOOPT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+
+# ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+
+# ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+
+# ifdef EOPNOTSUPP
+ case EOPNOTSUPP:
+ return P_ERROR_IO_NOT_SUPPORTED;
+# endif
+
+# ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef ENETUNREACH
+ case ENETUNREACH:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef ENETDOWN
+ case ENETDOWN:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef EHOSTDOWN
+ case EHOSTDOWN:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef ENONET
+ case ENONET:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+ return P_ERROR_IO_NOT_AVAILABLE;
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+ return P_ERROR_IO_IN_PROGRESS;
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+ return P_ERROR_IO_IN_PROGRESS;
+# endif
+
+# ifdef EISCONN
+ case EISCONN:
+ return P_ERROR_IO_CONNECTED;
+# endif
+
+# ifdef ECONNREFUSED
+ case ECONNREFUSED:
+ return P_ERROR_IO_CONNECTION_REFUSED;
+# endif
+
+# ifdef ENOTCONN
+ case ENOTCONN:
+ return P_ERROR_IO_NOT_CONNECTED;
+# endif
+
+# ifdef ECONNABORTED
+ case ECONNABORTED:
+ return P_ERROR_IO_ABORTED;
+# endif
+
+# ifdef EADDRINUSE
+ case EADDRINUSE:
+ return P_ERROR_IO_ADDRESS_IN_USE;
+# endif
+
+# ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ return P_ERROR_IO_TIMED_OUT;
+# endif
+
+# ifdef EDQUOT
+ case EDQUOT:
+ return P_ERROR_IO_QUOTA;
+# endif
+
+# ifdef EISDIR
+ case EISDIR:
+ return P_ERROR_IO_IS_DIRECTORY;
+# endif
+
+# ifdef ENOTDIR
+ case ENOTDIR:
+ return P_ERROR_IO_NOT_DIRECTORY;
+# endif
+
+# ifdef EEXIST
+ case EEXIST:
+ return P_ERROR_IO_EXISTS;
+# endif
+
+# ifdef ENOENT
+ case ENOENT:
+ return P_ERROR_IO_NOT_EXISTS;
+# endif
+
+# ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ return P_ERROR_IO_NAMETOOLONG;
+# endif
+
+# ifdef ENOSYS
+ case ENOSYS:
+ return P_ERROR_IO_NOT_IMPLEMENTED;
+# endif
+
+ /* Some magic to deal with EWOULDBLOCK and EAGAIN.
+ * Apparently on HP-UX these are actually defined to different values,
+ * but on Linux, for example, they are the same. */
+# if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK == EAGAIN
+ /* We have both and they are the same: only emit one case. */
+ case EAGAIN:
+ return P_ERROR_IO_WOULD_BLOCK;
+# else
+ /* Else: consider each of them separately. This handles both the
+ * case of having only one and the case where they are different values. */
+# ifdef EAGAIN
+ case EAGAIN:
+ return P_ERROR_IO_WOULD_BLOCK;
+# endif
+
+# ifdef EWOULDBLOCK
+ case EWOULDBLOCK:
+ return P_ERROR_IO_WOULD_BLOCK;
+# endif
+# endif
+#endif /* !P_OS_WIN */
+ default:
+ return P_ERROR_IO_FAILED;
+ }
+}
+
+PErrorIO
+p_error_get_last_io (void)
+{
+ return p_error_get_io_from_system (p_error_get_last_system ());
+}
+
+PErrorIPC
+p_error_get_ipc_from_system (pint err_code)
+{
+ switch (err_code) {
+ case 0:
+ return P_ERROR_IPC_NONE;
+#ifdef P_OS_WIN
+# ifdef ERROR_ALREADY_EXISTS
+ case ERROR_ALREADY_EXISTS:
+ return P_ERROR_IPC_EXISTS;
+# endif
+# ifdef ERROR_SEM_OWNER_DIED
+ case ERROR_SEM_OWNER_DIED:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+# ifdef ERROR_SEM_NOT_FOUND
+ case ERROR_SEM_NOT_FOUND:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+# ifdef ERROR_SEM_USER_LIMIT
+ case ERROR_SEM_USER_LIMIT:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_TOO_MANY_SEMAPHORES
+ case ERROR_TOO_MANY_SEMAPHORES:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_ACCESS_DENIED
+ case ERROR_ACCESS_DENIED:
+ return P_ERROR_IPC_ACCESS;
+# endif
+# ifdef ERROR_EXCL_SEM_ALREADY_OWNED
+ case ERROR_EXCL_SEM_ALREADY_OWNED:
+ return P_ERROR_IPC_ACCESS;
+# endif
+# ifdef ERROR_TOO_MANY_SEM_REQUESTS
+ case ERROR_TOO_MANY_SEM_REQUESTS:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_TOO_MANY_POSTS
+ case ERROR_TOO_MANY_POSTS:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_OUTOFMEMORY
+ case ERROR_OUTOFMEMORY:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_NOT_ENOUGH_MEMORY
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_INVALID_HANDLE
+ case ERROR_INVALID_HANDLE:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_INVALID_PARAMETER
+ case ERROR_INVALID_PARAMETER:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_NOT_SUPPORTED
+ case ERROR_NOT_SUPPORTED:
+ return P_ERROR_IPC_NOT_IMPLEMENTED;
+# endif
+#elif defined (P_OS_OS2)
+# ifdef ERROR_NOT_ENOUGH_MEMORY
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_INVALID_PARAMETER
+ case ERROR_INVALID_PARAMETER:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_INVALID_NAME
+ case ERROR_INVALID_NAME:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_INVALID_HANDLE
+ case ERROR_INVALID_HANDLE:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_FILE_NOT_FOUND
+ case ERROR_FILE_NOT_FOUND:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+# ifdef ERROR_INVALID_ADDRESS
+ case ERROR_INVALID_ADDRESS:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+# ifdef ERROR_GEN_FAILURE
+ case ERROR_GEN_FAILURE:
+ return P_ERROR_IPC_FAILED;
+# endif
+# ifdef ERROR_LOCKED
+ case ERROR_LOCKED:
+ return P_ERROR_IPC_ACCESS;
+# endif
+# ifdef ERROR_DUPLICATE_NAME
+ case ERROR_DUPLICATE_NAME:
+ return P_ERROR_IPC_EXISTS;
+# endif
+# ifdef ERROR_TOO_MANY_HANDLES
+ case ERROR_TOO_MANY_HANDLES:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_TOO_MANY_OPENS
+ case ERROR_TOO_MANY_OPENS:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_TOO_MANY_SEM_REQUESTS
+ case ERROR_TOO_MANY_SEM_REQUESTS:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+# ifdef ERROR_SEM_OWNER_DIED
+ case ERROR_SEM_OWNER_DIED:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+# ifdef ERROR_NOT_OWNER
+ case ERROR_NOT_OWNER:
+ return P_ERROR_IPC_ACCESS;
+# endif
+# ifdef ERROR_SEM_NOT_FOUND
+ case ERROR_SEM_NOT_FOUND:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+#else /* !P_OS_WINDOWS && !P_OS_OS2 */
+# ifdef EACCES
+ case EACCES:
+ return P_ERROR_IPC_ACCESS;
+# endif
+
+# ifdef EPERM
+ case EPERM:
+ return P_ERROR_IPC_ACCESS;
+# endif
+
+# ifdef EEXIST
+ case EEXIST:
+ return P_ERROR_IPC_EXISTS;
+# endif
+
+# ifdef E2BIG
+ case E2BIG:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef EFAULT
+ case EFAULT:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef EFBIG
+ case EFBIG:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef EINVAL
+ case EINVAL:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef ELOOP
+ case ELOOP:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef ERANGE
+ case ERANGE:
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+# endif
+
+# ifdef ENOMEM
+ case ENOMEM:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+
+# ifdef EMFILE
+ case EMFILE:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+
+# ifdef ENFILE
+ case ENFILE:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+
+# ifdef ENOSPC
+ case ENOSPC:
+ return P_ERROR_IPC_NO_RESOURCES;
+# endif
+
+# ifdef EIDRM
+ case EIDRM:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+
+# ifdef ENOENT
+ case ENOENT:
+ return P_ERROR_IPC_NOT_EXISTS;
+# endif
+
+# ifdef EOVERFLOW
+ case EOVERFLOW:
+ return P_ERROR_IPC_OVERFLOW;
+# endif
+
+# ifdef ENOSYS
+ case ENOSYS:
+ return P_ERROR_IPC_NOT_IMPLEMENTED;
+# endif
+
+# ifdef EDEADLK
+ case EDEADLK:
+ return P_ERROR_IPC_DEADLOCK;
+# endif
+
+# ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ return P_ERROR_IPC_NAMETOOLONG;
+# endif
+#endif /* !P_OS_WIN */
+ default:
+ return P_ERROR_IPC_FAILED;
+ }
+}
+
+PErrorIPC
+p_error_get_last_ipc (void)
+{
+ return p_error_get_ipc_from_system (p_error_get_last_system ());
+}
+
+P_LIB_API PError *
+p_error_new (void)
+{
+ PError *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PError))) == NULL))
+ return NULL;
+
+ return ret;
+}
+
+P_LIB_API PError *
+p_error_new_literal (pint code,
+ pint native_code,
+ const pchar *message)
+{
+ PError *ret;
+
+ if (P_UNLIKELY ((ret = p_error_new ()) == NULL))
+ return NULL;
+
+ ret->code = code;
+ ret->native_code = native_code;
+ ret->message = p_strdup (message);
+
+ return ret;
+}
+
+P_LIB_API const pchar *
+p_error_get_message (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return NULL;
+
+ return error->message;
+}
+
+P_LIB_API pint
+p_error_get_code (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return 0;
+
+ return error->code;
+}
+
+P_LIB_API pint
+p_error_get_native_code (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return 0;
+
+ return error->native_code;
+}
+
+P_LIB_API PErrorDomain
+p_error_get_domain (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return P_ERROR_DOMAIN_NONE;
+
+ if (error->code >= (pint) P_ERROR_DOMAIN_IPC)
+ return P_ERROR_DOMAIN_IPC;
+ else if (error->code >= (pint) P_ERROR_DOMAIN_IO)
+ return P_ERROR_DOMAIN_IO;
+ else
+ return P_ERROR_DOMAIN_NONE;
+}
+
+P_LIB_API PError *
+p_error_copy (PError *error)
+{
+ PError *ret;
+
+ if (P_UNLIKELY (error == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_error_new_literal (error->code,
+ error->native_code,
+ error->message)) == NULL))
+ return NULL;
+
+ return ret;
+}
+
+P_LIB_API void
+p_error_set_error (PError *error,
+ pint code,
+ pint native_code,
+ const pchar *message)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ if (error->message != NULL)
+ p_free (error->message);
+
+ error->code = code;
+ error->native_code = native_code;
+ error->message = p_strdup (message);
+}
+
+P_LIB_API void
+p_error_set_error_p (PError **error,
+ pint code,
+ pint native_code,
+ const pchar *message)
+{
+ if (error == NULL || *error != NULL)
+ return;
+
+ *error = p_error_new_literal (code, native_code, message);
+}
+
+P_LIB_API void
+p_error_set_code (PError *error,
+ pint code)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ error->code = code;
+}
+
+P_LIB_API void
+p_error_set_native_code (PError *error,
+ pint native_code)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ error->native_code = native_code;
+}
+
+P_LIB_API void
+p_error_set_message (PError *error,
+ const pchar *message)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ if (error->message != NULL)
+ p_free (error->message);
+
+ error->message = p_strdup (message);
+}
+
+P_LIB_API void
+p_error_clear (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ if (error->message != NULL)
+ p_free (error->message);
+
+ error->message = NULL;
+ error->code = 0;
+ error->native_code = 0;
+}
+
+P_LIB_API void
+p_error_free (PError *error)
+{
+ if (P_UNLIKELY (error == NULL))
+ return;
+
+ if (error->message != NULL)
+ p_free (error->message);
+
+ p_free (error);
+}
+
+P_LIB_API pint
+p_error_get_last_system (void)
+{
+#ifdef P_OS_WIN
+ return (pint) GetLastError ();
+#else
+# ifdef P_OS_VMS
+ pint error_code = errno;
+
+ if (error_code == EVMSERR)
+ return vaxc$errno;
+ else
+ return error_code;
+# else
+ return errno;
+# endif
+#endif
+}
+
+P_LIB_API pint
+p_error_get_last_net (void)
+{
+#if defined (P_OS_WIN)
+ return WSAGetLastError ();
+#elif defined (P_OS_OS2)
+ return sock_errno ();
+#else
+ return p_error_get_last_system ();
+#endif
+}
+
+P_LIB_API void
+p_error_set_last_system (pint code)
+{
+#ifdef P_OS_WIN
+ SetLastError (code);
+#else
+ errno = code;
+#endif
+}
+
+P_LIB_API void
+p_error_set_last_net (pint code)
+{
+#if defined (P_OS_WIN)
+ WSASetLastError (code);
+#elif defined (P_OS_OS2)
+ P_UNUSED (code);
+#else
+ errno = code;
+#endif
+}
diff --git a/3rdparty/plibsys/src/perror.h b/3rdparty/plibsys/src/perror.h
new file mode 100644
index 0000000..c08f53f
--- /dev/null
+++ b/3rdparty/plibsys/src/perror.h
@@ -0,0 +1,249 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file perror.h
+ * @brief Error report system
+ * @author Alexander Saprykin
+ *
+ * An error report system is used to notify a caller about fatal situations
+ * during the library API invocation. Usually the sequence is as following:
+ * @code
+ * PError *error = NULL;
+ * ...
+ *
+ * if (error != NULL) {
+ * ...
+ * p_error_free (error);
+ * }
+ * @endcode
+ * Note that you should not initialize a new #PError object before passing the
+ * pointer into an API call. Simply initialize it with zero and check the result
+ * after. Therefore you need to free memory if an error occurred.
+ *
+ * Most operating systems store the last error code of the most system calls in
+ * a thread-specific variable. Moreover, Windows stores the error code of the
+ * last socket related call in a separate variable. Use
+ * p_error_get_last_system() and p_error_set_last_system() to access the last
+ * system error code, p_error_get_last_net() and p_error_set_last_net() to
+ * access the last network error code.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PERROR_H
+#define PLIBSYS_HEADER_PERROR_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perrortypes.h>
+
+P_BEGIN_DECLS
+
+/** Opaque data structure for an error object. */
+typedef struct PError_ PError;
+
+/**
+ * @brief Initializes a new empty #PError.
+ * @return Newly initialized #PError object in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PError * p_error_new (void);
+
+/**
+ * @brief Initializes a new #PError with data.
+ * @param code Error code.
+ * @param native_code Native error code, leave 0 to ignore.
+ * @param message Error message.
+ * @return Newly initialized #PError object in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PError * p_error_new_literal (pint code,
+ pint native_code,
+ const pchar *message);
+
+/**
+ * @brief Gets an error message.
+ * @param error #PError object to get the message from.
+ * @return Error message in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API const pchar * p_error_get_message (PError *error);
+
+/**
+ * @brief Gets an error code.
+ * @param error #PError object to get the code from.
+ * @return Error code in case of success, 0 otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pint p_error_get_code (PError *error);
+
+/**
+ * @brief Gets a platform native error code, if any.
+ * @param error #PError object to get the native code from.
+ * @return Error code in case of success, 0 otherwise.
+ * @since 0.0.1
+ * @note In some situations there can be no native code error, i.e. when an
+ * internal library call failed. Do not rely on this code.
+ */
+P_LIB_API pint p_error_get_native_code (PError *error);
+
+/**
+ * @brief Gets an error domain.
+ * @param error #PError object to get the domain from.
+ * @return Error domain in case of success, #P_ERROR_DOMAIN_NONE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PErrorDomain p_error_get_domain (PError *error);
+
+/**
+ * @brief Creates a copy of a #PError object.
+ * @param error #PError object to copy.
+ * @return Newly created #PError object in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note The caller is responsible to free memory of the created object after
+ * usage.
+ */
+P_LIB_API PError * p_error_copy (PError *error);
+
+/**
+ * @brief Sets error data.
+ * @param error #PError object to set the data for.
+ * @param code Error code.
+ * @param native_code Native error code, leave 0 to ignore.
+ * @param message Error message.
+ * @since 0.0.1
+ */
+P_LIB_API void p_error_set_error (PError *error,
+ pint code,
+ pint native_code,
+ const pchar *message);
+
+/**
+ * @brief Sets error data through a double pointer.
+ * @param error #PError object to set the data for.
+ * @param code Error code.
+ * @param native_code Native error code, leave 0 to ignore.
+ * @param message Error message.
+ * @since 0.0.1
+ *
+ * If @a error is NULL it does nothing. If @a error is not NULL then @a *error
+ * should be NULL, otherwise it does nothing. It creates a #PError object, sets
+ * error data and assigns it to @a *error. The caller is responsible to free
+ * memory of the created object after usage.
+ */
+P_LIB_API void p_error_set_error_p (PError **error,
+ pint code,
+ pint native_code,
+ const pchar *message);
+
+/**
+ * @brief Sets an error code.
+ * @param error #PError object to set the code for.
+ * @param code Error code.
+ * @since 0.0.1
+ */
+P_LIB_API void p_error_set_code (PError *error,
+ pint code);
+
+/**
+ * @brief Sets a platform native error code.
+ * @param error #PError object to set the native error code for.
+ * @param native_code Platform native error code.
+ * @since 0.0.1
+ */
+P_LIB_API void p_error_set_native_code (PError *error,
+ pint native_code);
+
+/**
+ * @brief Sets an error message.
+ * @param error #PError object to set the message for.
+ * @param message Error message.
+ * @since 0.0.1
+ */
+P_LIB_API void p_error_set_message (PError *error,
+ const pchar *message);
+
+/**
+ * @brief Clears error data.
+ * @param error #PError object to clear the data for.
+ * @since 0.0.1
+ * @note Error code is reseted to 0.
+ */
+P_LIB_API void p_error_clear (PError *error);
+
+/**
+ * @brief Frees a previously initialized error object.
+ * @param error #PError object to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_error_free (PError *error);
+
+/**
+ * @brief Gets the last system native error code.
+ * @return Last system native error code.
+ * @since 0.0.2
+ * @sa p_error_get_last_net(), p_error_set_last_system(),
+ * p_error_set_last_net()
+ * @note If you want get an error code for socket-related calls, use
+ * p_error_get_last_net() instead.
+ */
+
+P_LIB_API pint p_error_get_last_system (void);
+
+/**
+ * @brief Gets the last network native error code.
+ * @return Last network native error code.
+ * @since 0.0.2
+ * @sa p_error_get_last_system(), p_error_set_last_net(),
+ * p_error_set_last_system()
+ */
+P_LIB_API pint p_error_get_last_net (void);
+
+/**
+ * @brief Sets the last system native error code.
+ * @param code Error code to set.
+ * @since 0.0.2
+ * @sa p_error_set_last_net(), p_error_get_last_system(),
+ * p_error_get_last_net()
+ * @note If you want set an error code for socket-related calls, use
+ * p_error_set_last_net() instead.
+ */
+P_LIB_API void p_error_set_last_system (pint code);
+
+/**
+ * @brief Sets the last network native error code.
+ * @param code Error code to set.
+ * @since 0.0.2
+ * @sa p_error_set_last_system(), p_error_get_last_net(),
+ * p_error_get_last_system()
+ */
+P_LIB_API void p_error_set_last_net (pint code);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PERROR_H */
diff --git a/3rdparty/plibsys/src/perrortypes.h b/3rdparty/plibsys/src/perrortypes.h
new file mode 100644
index 0000000..e935c8a
--- /dev/null
+++ b/3rdparty/plibsys/src/perrortypes.h
@@ -0,0 +1,106 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file perrortypes.h
+ * @brief Error data types
+ * @author Alexander Saprykin
+ *
+ * All error codes are splitted into the several domains. Every error should
+ * belong to one of the domains described in #PErrorDomain. Think of an error
+ * domain as a logical subsystem.
+ *
+ * Every error domain has its own enumeration with the list of possible error
+ * codes. System error codes are converted to specified domains using internal
+ * routines.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PERRORTYPES_H
+#define PLIBSYS_HEADER_PERRORTYPES_H
+
+#include <pmacros.h>
+
+P_BEGIN_DECLS
+
+/** Enum with error domains. */
+typedef enum PErrorDomain_ {
+ P_ERROR_DOMAIN_NONE = 0, /**< No domain was specified. */
+ P_ERROR_DOMAIN_IO = 500, /**< Input/output domain. */
+ P_ERROR_DOMAIN_IPC = 600 /**< Interprocess communication domain. */
+} PErrorDomain;
+
+/** Enum with IO errors. */
+typedef enum PErrorIO_ {
+ P_ERROR_IO_NONE = 500, /**< No error. */
+ P_ERROR_IO_NO_RESOURCES = 501, /**< Operating system hasn't enough resources. */
+ P_ERROR_IO_NOT_AVAILABLE = 502, /**< Resource isn't available. */
+ P_ERROR_IO_ACCESS_DENIED = 503, /**< Access denied. */
+ P_ERROR_IO_CONNECTED = 504, /**< Already connected. */
+ P_ERROR_IO_IN_PROGRESS = 505, /**< Operation in progress. */
+ P_ERROR_IO_ABORTED = 506, /**< Operation aborted. */
+ P_ERROR_IO_INVALID_ARGUMENT = 507, /**< Invalid argument specified. */
+ P_ERROR_IO_NOT_SUPPORTED = 508, /**< Operation not supported. */
+ P_ERROR_IO_TIMED_OUT = 509, /**< Operation timed out. */
+ P_ERROR_IO_WOULD_BLOCK = 510, /**< Operation cannot be completed immediatly. */
+ P_ERROR_IO_ADDRESS_IN_USE = 511, /**< Address is already under usage. */
+ P_ERROR_IO_CONNECTION_REFUSED = 512, /**< Connection refused. */
+ P_ERROR_IO_NOT_CONNECTED = 513, /**< Connection required first. */
+ P_ERROR_IO_QUOTA = 514, /**< User quota exceeded. */
+ P_ERROR_IO_IS_DIRECTORY = 515, /**< Trying to open directory for writing. */
+ P_ERROR_IO_NOT_DIRECTORY = 516, /**< Component of the path prefix is not a directory. */
+ P_ERROR_IO_NAMETOOLONG = 517, /**< Specified name is too long. */
+ P_ERROR_IO_EXISTS = 518, /**< Specified entry already exists. */
+ P_ERROR_IO_NOT_EXISTS = 519, /**< Specified entry doesn't exist. */
+ P_ERROR_IO_NO_MORE = 520, /**< No more data left. */
+ P_ERROR_IO_NOT_IMPLEMENTED = 521, /**< Operation is not implemented. */
+ P_ERROR_IO_FAILED = 522 /**< General error. */
+} PErrorIO;
+
+/** Enum with IPC errors */
+typedef enum PErrorIPC_ {
+ P_ERROR_IPC_NONE = 600, /**< No error. */
+ P_ERROR_IPC_ACCESS = 601, /**< Not enough rights to access object or its key. */
+ P_ERROR_IPC_EXISTS = 602, /**< Object already exists and no proper open flags
+ were specified. */
+ P_ERROR_IPC_NOT_EXISTS = 603, /**< Object doesn't exist or was removed before, and
+ no proper create flags were specified. */
+ P_ERROR_IPC_NO_RESOURCES = 604, /**< Not enough system resources or memory to perform
+ operation. */
+ P_ERROR_IPC_OVERFLOW = 605, /**< Semaphore value overflow. */
+ P_ERROR_IPC_NAMETOOLONG = 606, /**< Object name is too long. */
+ P_ERROR_IPC_INVALID_ARGUMENT = 607, /**< Invalid argument (parameter) specified. */
+ P_ERROR_IPC_NOT_IMPLEMENTED = 608, /**< Operation is not implemented (for example when
+ using some filesystems). */
+ P_ERROR_IPC_DEADLOCK = 609, /**< Deadlock detected. */
+ P_ERROR_IPC_FAILED = 610 /**< General error. */
+} PErrorIPC;
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PERRORTYPES_H */
diff --git a/3rdparty/plibsys/src/pfile.c b/3rdparty/plibsys/src/pfile.c
new file mode 100644
index 0000000..905b2d7
--- /dev/null
+++ b/3rdparty/plibsys/src/pfile.c
@@ -0,0 +1,80 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "perror-private.h"
+
+#ifndef P_OS_WIN
+# include <unistd.h>
+#endif
+
+P_LIB_API pboolean
+p_file_is_exists (const pchar *file)
+{
+#ifdef P_OS_WIN
+ DWORD attrs;
+#endif
+
+ if (P_UNLIKELY (file == NULL))
+ return FALSE;
+
+#ifdef P_OS_WIN
+ attrs = GetFileAttributesA ((LPCSTR) file);
+
+ return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0);
+#else
+ return access (file, F_OK) == 0;
+#endif
+}
+
+P_LIB_API pboolean
+p_file_remove (const pchar *file,
+ PError **error)
+{
+ pboolean result;
+
+ if (P_UNLIKELY (file == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+#ifdef P_OS_WIN
+ result = (DeleteFileA ((LPCSTR) file) != 0);
+#else
+ result = (unlink (file) == 0);
+#endif
+
+ if (P_UNLIKELY (!result))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to remove file");
+
+ return result;
+}
diff --git a/3rdparty/plibsys/src/pfile.h b/3rdparty/plibsys/src/pfile.h
new file mode 100644
index 0000000..19748c9
--- /dev/null
+++ b/3rdparty/plibsys/src/pfile.h
@@ -0,0 +1,87 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pfile.h
+ * @brief File operations
+ * @author Alexander Saprykin
+ *
+ * To check file existance use p_file_is_exists(). To remove an exisiting file
+ * use p_file_remove().
+ *
+ * #P_DIR_SEPARATOR provides a platform independent directory separator symbol
+ * which you can use to form file or directory path.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PFILE_H
+#define PLIBSYS_HEADER_PFILE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perror.h>
+
+/**
+ * @def P_DIR_SEPARATOR
+ * @brief A directory separator.
+ */
+#if defined (P_OS_WIN) || defined (P_OS_OS2)
+# define P_DIR_SEPARATOR "\\"
+#else
+# define P_DIR_SEPARATOR "/"
+#endif
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Checks whether a file exists or not.
+ * @param file File name to check.
+ * @return TRUE if the file exists, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * On Windows this call doesn't resolve symbolic links, while on UNIX systems
+ * does.
+ */
+P_LIB_API pboolean p_file_is_exists (const pchar *file);
+
+/**
+ * @brief Removes a file from the disk.
+ * @param file File name to remove.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE if the file was successully removed, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * This call doesn't resolve symbolic links and remove a symbolic link if the
+ * given path points to it.
+ */
+P_LIB_API pboolean p_file_remove (const pchar *file,
+ PError **error);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PFILE_H */
diff --git a/3rdparty/plibsys/src/phashtable.c b/3rdparty/plibsys/src/phashtable.c
new file mode 100644
index 0000000..a9fc052
--- /dev/null
+++ b/3rdparty/plibsys/src/phashtable.c
@@ -0,0 +1,243 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Hash table organized like this: table[hash key]->[list with values]
+ * Note: this implementation is not intended to use on huge loads */
+
+#include "pmem.h"
+#include "phashtable.h"
+
+#include <stdlib.h>
+
+typedef struct PHashTableNode_ PHashTableNode;
+
+struct PHashTableNode_ {
+ PHashTableNode *next;
+ ppointer key;
+ ppointer value;
+};
+
+struct PHashTable_ {
+ PHashTableNode **table;
+ psize size;
+};
+
+/* Size of unique hash keys in hash table */
+#define P_HASH_TABLE_SIZE 101
+
+static puint pp_hash_table_calc_hash (pconstpointer pointer, psize modulo);
+static PHashTableNode * pp_hash_table_find_node (const PHashTable *table, pconstpointer key, puint hash);
+
+static puint
+pp_hash_table_calc_hash (pconstpointer pointer, psize modulo)
+{
+ /* As simple as we can :) */
+ return (puint) (((psize) (P_POINTER_TO_INT (pointer) + 37)) % modulo);
+}
+
+static PHashTableNode *
+pp_hash_table_find_node (const PHashTable *table, pconstpointer key, puint hash)
+{
+ PHashTableNode *ret;
+
+ for (ret = table->table[hash]; ret != NULL; ret = ret->next)
+ if (ret->key == key)
+ return ret;
+
+ return NULL;
+}
+
+P_LIB_API PHashTable *
+p_hash_table_new (void)
+{
+ PHashTable *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashTable))) == NULL)) {
+ P_ERROR ("PHashTable::p_hash_table_new: failed(1) to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->table = p_malloc0 (P_HASH_TABLE_SIZE * sizeof (PHashTableNode *))) == NULL)) {
+ P_ERROR ("PHashTable::p_hash_table_new: failed(2) to allocate memory");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->size = P_HASH_TABLE_SIZE;
+
+ return ret;
+}
+
+P_LIB_API void
+p_hash_table_insert (PHashTable *table, ppointer key, ppointer value)
+{
+ PHashTableNode *node;
+ puint hash;
+
+ if (P_UNLIKELY (table == NULL))
+ return;
+
+ hash = pp_hash_table_calc_hash (key, table->size);
+
+ if ((node = pp_hash_table_find_node (table, key, hash)) == NULL) {
+ if (P_UNLIKELY ((node = p_malloc0 (sizeof (PHashTableNode))) == NULL)) {
+ P_ERROR ("PHashTable::p_hash_table_insert: failed to allocate memory");
+ return;
+ }
+
+ /* Insert a new node in front of others */
+ node->key = key;
+ node->value = value;
+ node->next = table->table[hash];
+
+ table->table[hash] = node;
+ } else
+ node->value = value;
+}
+
+P_LIB_API ppointer
+p_hash_table_lookup (const PHashTable *table, pconstpointer key)
+{
+ PHashTableNode *node;
+ puint hash;
+
+ if (P_UNLIKELY (table == NULL))
+ return NULL;
+
+ hash = pp_hash_table_calc_hash (key, table->size);
+
+ return ((node = pp_hash_table_find_node (table, key, hash)) == NULL) ? (ppointer) (-1) : node->value;
+}
+
+P_LIB_API PList *
+p_hash_table_keys (const PHashTable *table)
+{
+ PList *ret = NULL;
+ PHashTableNode *node;
+ puint i;
+
+ if (P_UNLIKELY (table == NULL))
+ return NULL;
+
+ for (i = 0; i < table->size; ++i)
+ for (node = table->table[i]; node != NULL; node = node->next)
+ ret = p_list_append (ret, node->key);
+
+ return ret;
+}
+
+P_LIB_API PList *
+p_hash_table_values (const PHashTable *table)
+{
+ PList *ret = NULL;
+ PHashTableNode *node;
+ puint i;
+
+ if (P_UNLIKELY (table == NULL))
+ return NULL;
+
+ for (i = 0; i < table->size; ++i)
+ for (node = table->table[i]; node != NULL; node = node->next)
+ ret = p_list_append (ret, node->value);
+
+ return ret;
+}
+
+P_LIB_API void
+p_hash_table_free (PHashTable *table)
+{
+ PHashTableNode *node, *next_node;
+ puint i;
+
+ if (P_UNLIKELY (table == NULL))
+ return;
+
+ for (i = 0; i < table->size; ++i)
+ for (node = table->table[i]; node != NULL; ) {
+ next_node = node->next;
+ p_free (node);
+ node = next_node;
+ }
+
+ p_free (table->table);
+ p_free (table);
+}
+
+P_LIB_API void
+p_hash_table_remove (PHashTable *table, pconstpointer key)
+{
+ PHashTableNode *node, *prev_node;
+ puint hash;
+
+ if (P_UNLIKELY (table == NULL))
+ return;
+
+ hash = pp_hash_table_calc_hash (key, table->size);
+
+ if (pp_hash_table_find_node (table, key, hash) != NULL) {
+ node = table->table[hash];
+ prev_node = NULL;
+
+ while (node != NULL) {
+ if (node->key == key) {
+ if (prev_node == NULL)
+ table->table[hash] = node->next;
+ else
+ prev_node->next = node->next;
+
+ p_free (node);
+ break;
+ } else {
+ prev_node = node;
+ node = node->next;
+ }
+ }
+ }
+}
+
+P_LIB_API PList *
+p_hash_table_lookup_by_value (const PHashTable *table, pconstpointer val, PCompareFunc func)
+{
+ PList *ret = NULL;
+ PHashTableNode *node;
+ puint i;
+ pboolean res;
+
+ if (P_UNLIKELY (table == NULL))
+ return NULL;
+
+ for (i = 0; i < table->size; ++i)
+ for (node = table->table[i]; node != NULL; node = node->next) {
+ if (func == NULL)
+ res = (node->value == val);
+ else
+ res = (func (node->value, val) == 0);
+
+ if (res)
+ ret = p_list_append (ret, node->key);
+ }
+
+ return ret;
+}
diff --git a/3rdparty/plibsys/src/phashtable.h b/3rdparty/plibsys/src/phashtable.h
new file mode 100644
index 0000000..702bbe7
--- /dev/null
+++ b/3rdparty/plibsys/src/phashtable.h
@@ -0,0 +1,167 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file phashtable.h
+ * @brief Hash table
+ * @author Alexander Saprykin
+ *
+ * A hash table is a data structure used to map keys to values. The hash table
+ * consists of several internal slots which hold a list of values. A hash
+ * function is used to compute an index in the array of the slots from a given
+ * key. The hash function itself is fast and it takes a constant time to compute
+ * the internal slot index.
+ *
+ * When the number of pairs in the hash table is small the lookup and insert
+ * (remove) operations are very fast and have average complexity O(1), because
+ * every slot holds almost the only one pair. As the number of internal slots is
+ * fixed, the increasing number of pairs will lead to degraded performance and
+ * the average complexity of the operations can drop to O(N) in the worst case.
+ * This is because the more pairs are inserted the more longer the list of
+ * values is placed in every slot.
+ *
+ * This is a simple hash table implementation which is not intended for heavy
+ * usage (several thousands), see #PTree if you need the best performance on
+ * large data sets. This implementation doesn't support multi-inserts when
+ * several values belong to the same key.
+ *
+ * Note that #PHashTable stores keys and values only as pointers, so you need
+ * to free used memory manually, p_hash_table_free() will not do it in any way.
+ *
+ * Integers (up to 32 bits) can be stored in pointers using #P_POINTER_TO_INT
+ * and #P_INT_TO_POINTER macros.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PHASHTABLE_H
+#define PLIBSYS_HEADER_PHASHTABLE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <plist.h>
+
+P_BEGIN_DECLS
+
+/** Opaque data structure for a hash table. */
+typedef struct PHashTable_ PHashTable;
+
+/**
+ * @brief Initializes a new hash table.
+ * @return Pointer to a newly initialized #PHashTable structure in case of
+ * success, NULL otherwise.
+ * @since 0.0.1
+ * @note Free with p_hash_table_free() after usage.
+ */
+P_LIB_API PHashTable * p_hash_table_new (void);
+
+/**
+ * @brief Inserts a new key-value pair into a hash table.
+ * @param table Initialized hash table.
+ * @param key Key to insert.
+ * @param value Value to insert.
+ * @since 0.0.1
+ *
+ * This function only stores pointers, so you need to manually free pointed
+ * data after using the hash table.
+ */
+P_LIB_API void p_hash_table_insert (PHashTable *table,
+ ppointer key,
+ ppointer value);
+
+/**
+ * @brief Searches for a specifed key in the hash table.
+ * @param table Hash table to lookup in.
+ * @param key Key to lookup for.
+ * @return Value related to its key pair (can be NULL), (#ppointer) -1 if no
+ * value was found.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_hash_table_lookup (const PHashTable *table,
+ pconstpointer key);
+
+/**
+ * @brief Gives a list of all the stored keys in the hash table.
+ * @param table Hash table to collect the keys from.
+ * @return List of all the stored keys, the list can be empty if no keys were
+ * found.
+ * @since 0.0.1
+ * @note You should manually free the returned list with p_list_free() after
+ * using it.
+ */
+P_LIB_API PList * p_hash_table_keys (const PHashTable *table);
+
+/**
+ * @brief Gives a list of all the stored values in the hash table.
+ * @param table Hash table to collect the values from.
+ * @return List of all the stored values, the list can be empty if no keys were
+ * found.
+ * @since 0.0.1
+ * @note You should manually free the returned list with p_list_free() after
+ * using it.
+ */
+P_LIB_API PList * p_hash_table_values (const PHashTable *table);
+
+/**
+ * @brief Frees a previously initialized #PHashTable.
+ * @param table Hash table to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_hash_table_free (PHashTable *table);
+
+/**
+ * @brief Removes @a key from a hash table.
+ * @param table Hash table to remove the key from.
+ * @param key Key to remove (if exists).
+ * @since 0.0.1
+ */
+P_LIB_API void p_hash_table_remove (PHashTable *table,
+ pconstpointer key);
+
+/**
+ * @brief Searches for a specifed key in the hash table by its value.
+ * @param table Hash table to lookup in.
+ * @param val Value to lookup keys for.
+ * @param func Function to compare table's values with @a val, if NULL then
+ * values will be compared as pointers.
+ * @return List of the keys with @a val (can be NULL), NULL if no keys were
+ * found.
+ * @since 0.0.1
+ * @note Caller is responsible to call p_list_free() on the returned list after
+ * usage.
+ *
+ * The compare function should return 0 if a value from the hash table (the
+ * first parameter) is accepted related to the given lookup value (the second
+ * parameter), and -1 or 1 otherwise.
+ */
+P_LIB_API PList * p_hash_table_lookup_by_value (const PHashTable *table,
+ pconstpointer val,
+ PCompareFunc func);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PHASHTABLE_H */
diff --git a/3rdparty/plibsys/src/pinifile.c b/3rdparty/plibsys/src/pinifile.c
new file mode 100644
index 0000000..d8361fc
--- /dev/null
+++ b/3rdparty/plibsys/src/pinifile.c
@@ -0,0 +1,503 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2012-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pinifile.h"
+#include "plist.h"
+#include "pmem.h"
+#include "pstring.h"
+#include "perror-private.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define P_INI_FILE_MAX_LINE 1024
+
+typedef struct PIniParameter_ {
+ pchar *name;
+ pchar *value;
+} PIniParameter;
+
+typedef struct PIniSection_ {
+ pchar *name;
+ PList *keys;
+} PIniSection;
+
+struct PIniFile_ {
+ pchar *path;
+ PList *sections;
+ pboolean is_parsed;
+};
+
+static PIniParameter * pp_ini_file_parameter_new (const pchar *name, const pchar *val);
+static void pp_ini_file_parameter_free (PIniParameter *param);
+static PIniSection * pp_ini_file_section_new (const pchar *name);
+static void pp_ini_file_section_free (PIniSection *section);
+static pchar * pp_ini_file_find_parameter (const PIniFile *file, const pchar *section, const pchar *key);
+
+static PIniParameter *
+pp_ini_file_parameter_new (const pchar *name,
+ const pchar *val)
+{
+ PIniParameter *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PIniParameter))) == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret->name = p_strdup (name)) == NULL)) {
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->value = p_strdup (val)) == NULL)) {
+ p_free (ret->name);
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static void
+pp_ini_file_parameter_free (PIniParameter *param)
+{
+ p_free (param->name);
+ p_free (param->value);
+ p_free (param);
+}
+
+static PIniSection *
+pp_ini_file_section_new (const pchar *name)
+{
+ PIniSection *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PIniSection))) == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret->name = p_strdup (name)) == NULL)) {
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static void
+pp_ini_file_section_free (PIniSection *section)
+{
+ p_list_foreach (section->keys, (PFunc) pp_ini_file_parameter_free, NULL);
+ p_list_free (section->keys);
+ p_free (section->name);
+ p_free (section);
+}
+
+static pchar *
+pp_ini_file_find_parameter (const PIniFile *file, const pchar *section, const pchar *key)
+{
+ PList *item;
+
+ if (P_UNLIKELY (file == NULL || file->is_parsed == FALSE || section == NULL || key == NULL))
+ return NULL;
+
+ for (item = file->sections; item != NULL; item = item->next)
+ if (strcmp (((PIniSection *) item->data)->name, section) == 0)
+ break;
+
+ if (item == NULL)
+ return NULL;
+
+ for (item = ((PIniSection *) item->data)->keys; item != NULL; item = item->next)
+ if (strcmp (((PIniParameter *) item->data)->name, key) == 0)
+ return p_strdup (((PIniParameter *) item->data)->value);
+
+ return NULL;
+}
+
+P_LIB_API PIniFile *
+p_ini_file_new (const pchar *path)
+{
+ PIniFile *ret;
+
+ if (P_UNLIKELY (path == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PIniFile))) == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret->path = p_strdup (path)) == NULL)) {
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->is_parsed = FALSE;
+
+ return ret;
+}
+
+P_LIB_API void
+p_ini_file_free (PIniFile *file)
+{
+ if (P_UNLIKELY (file == NULL))
+ return;
+
+ p_list_foreach (file->sections, (PFunc) pp_ini_file_section_free, NULL);
+ p_list_free (file->sections);
+ p_free (file->path);
+ p_free (file);
+}
+
+P_LIB_API pboolean
+p_ini_file_parse (PIniFile *file,
+ PError **error)
+{
+ PIniSection *section;
+ PIniParameter *param;
+ FILE *in_file;
+ pchar *dst_line, *tmp_str;
+ pchar src_line[P_INI_FILE_MAX_LINE + 1],
+ key[P_INI_FILE_MAX_LINE + 1],
+ value[P_INI_FILE_MAX_LINE + 1];
+ pint bom_shift;
+
+ if (P_UNLIKELY (file == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (file->is_parsed)
+ return TRUE;
+
+ if (P_UNLIKELY ((in_file = fopen (file->path, "r")) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to open file for reading");
+ return FALSE;
+ }
+
+ dst_line = NULL;
+ section = NULL;
+ param = NULL;
+
+ memset (src_line, 0, sizeof (src_line));
+
+ while (fgets (src_line, sizeof (src_line), in_file) != NULL) {
+ /* UTF-8, UTF-16 and UTF-32 BOM detection */
+ if ((puchar) src_line[0] == 0xEF && (puchar) src_line[1] == 0xBB && (puchar) src_line[2] == 0xBF)
+ bom_shift = 3;
+ else if (((puchar) src_line[0] == 0xFE && (puchar) src_line[1] == 0xFF) ||
+ ((puchar) src_line[0] == 0xFF && (puchar) src_line[1] == 0xFE))
+ bom_shift = 2;
+ else if ((puchar) src_line[0] == 0x00 && (puchar) src_line[1] == 0x00 &&
+ (puchar) src_line[2] == 0xFE && (puchar) src_line[3] == 0xFF)
+ bom_shift = 4;
+ else if ((puchar) src_line[0] == 0xFF && (puchar) src_line[1] == 0xFE &&
+ (puchar) src_line[2] == 0x00 && (puchar) src_line[3] == 0x00)
+ bom_shift = 4;
+ else
+ bom_shift = 0;
+
+ dst_line = p_strchomp (src_line + bom_shift);
+
+ if (dst_line == NULL)
+ continue;
+
+ /* This should not happen */
+ if (P_UNLIKELY (strlen (dst_line) > P_INI_FILE_MAX_LINE))
+ dst_line[P_INI_FILE_MAX_LINE] = '\0';
+
+ if (dst_line[0] == '[' && dst_line[strlen (dst_line) - 1] == ']' &&
+ sscanf (dst_line, "[%[^]]", key) == 1) {
+ /* New section found */
+ if ((tmp_str = p_strchomp (key)) != NULL) {
+ /* This should not happen */
+ if (P_UNLIKELY (strlen (tmp_str) > P_INI_FILE_MAX_LINE))
+ tmp_str[P_INI_FILE_MAX_LINE] = '\0';
+
+ strcpy (key, tmp_str);
+ p_free (tmp_str);
+
+ if (section != NULL) {
+ if (section->keys == NULL)
+ pp_ini_file_section_free (section);
+ else
+ file->sections = p_list_prepend (file->sections, section);
+ }
+
+ section = pp_ini_file_section_new (key);
+ }
+ } else if (sscanf (dst_line, "%[^=] = \"%[^\"]\"", key, value) == 2 ||
+ sscanf (dst_line, "%[^=] = '%[^\']'", key, value) == 2 ||
+ sscanf (dst_line, "%[^=] = %[^;#]", key, value) == 2) {
+ /* New parameter found */
+ if ((tmp_str = p_strchomp (key)) != NULL) {
+ /* This should not happen */
+ if (P_UNLIKELY (strlen (tmp_str) > P_INI_FILE_MAX_LINE))
+ tmp_str[P_INI_FILE_MAX_LINE] = '\0';
+
+ strcpy (key, tmp_str);
+ p_free (tmp_str);
+
+ if ((tmp_str = p_strchomp (value)) != NULL) {
+ /* This should not happen */
+ if (P_UNLIKELY (strlen (tmp_str) > P_INI_FILE_MAX_LINE))
+ tmp_str[P_INI_FILE_MAX_LINE] = '\0';
+
+ strcpy (value, tmp_str);
+ p_free (tmp_str);
+
+ if (strcmp (value, "\"\"") == 0 || (strcmp (value, "''") == 0))
+ value[0] = '\0';
+
+ if (section != NULL && (param = pp_ini_file_parameter_new (key, value)) != NULL)
+ section->keys = p_list_prepend (section->keys, param);
+ }
+ }
+ }
+
+ p_free (dst_line);
+ memset (src_line, 0, sizeof (src_line));
+ }
+
+ if (section != NULL) {
+ if (section->keys == NULL)
+ pp_ini_file_section_free (section);
+ else
+ file->sections = p_list_append (file->sections, section);
+ }
+
+ if (P_UNLIKELY (fclose (in_file) != 0))
+ P_WARNING ("PIniFile::p_ini_file_parse: fclose() failed");
+
+ file->is_parsed = TRUE;
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_ini_file_is_parsed (const PIniFile *file)
+{
+ if (P_UNLIKELY (file == NULL))
+ return FALSE;
+
+ return file->is_parsed;
+}
+
+P_LIB_API PList *
+p_ini_file_sections (const PIniFile *file)
+{
+ PList *ret;
+ PList *sec;
+
+ if (P_UNLIKELY (file == NULL || file->is_parsed == FALSE))
+ return NULL;
+
+ ret = NULL;
+
+ for (sec = file->sections; sec != NULL; sec = sec->next)
+ ret = p_list_prepend (ret, p_strdup (((PIniSection *) sec->data)->name));
+
+ return ret;
+}
+
+P_LIB_API PList *
+p_ini_file_keys (const PIniFile *file,
+ const pchar *section)
+{
+ PList *ret;
+ PList *item;
+
+ if (P_UNLIKELY (file == NULL || file->is_parsed == FALSE || section == NULL))
+ return NULL;
+
+ ret = NULL;
+
+ for (item = file->sections; item != NULL; item = item->next)
+ if (strcmp (((PIniSection *) item->data)->name, section) == 0)
+ break;
+
+ if (item == NULL)
+ return NULL;
+
+ for (item = ((PIniSection *) item->data)->keys; item != NULL; item = item->next)
+ ret = p_list_prepend (ret, p_strdup (((PIniParameter *) item->data)->name));
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_ini_file_is_key_exists (const PIniFile *file,
+ const pchar *section,
+ const pchar *key)
+{
+ PList *item;
+
+ if (P_UNLIKELY (file == NULL || file->is_parsed == FALSE || section == NULL || key == NULL))
+ return FALSE;
+
+ for (item = file->sections; item != NULL; item = item->next)
+ if (strcmp (((PIniSection *) item->data)->name, section) == 0)
+ break;
+
+ if (item == NULL)
+ return FALSE;
+
+ for (item = ((PIniSection *) item->data)->keys; item != NULL; item = item->next)
+ if (strcmp (((PIniParameter *) item->data)->name, key) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+P_LIB_API pchar *
+p_ini_file_parameter_string (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ const pchar *default_val)
+{
+ pchar *val;
+
+ if ((val = pp_ini_file_find_parameter (file, section, key)) == NULL)
+ return p_strdup (default_val);
+
+ return val;
+}
+
+P_LIB_API pint
+p_ini_file_parameter_int (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ pint default_val)
+{
+ pchar *val;
+ pint ret;
+
+ if ((val = pp_ini_file_find_parameter (file, section, key)) == NULL)
+ return default_val;
+
+ ret = atoi (val);
+ p_free (val);
+
+ return ret;
+}
+
+P_LIB_API double
+p_ini_file_parameter_double (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ double default_val)
+{
+ pchar *val;
+ pdouble ret;
+
+ if ((val = pp_ini_file_find_parameter (file, section, key)) == NULL)
+ return default_val;
+
+ ret = p_strtod (val);
+ p_free (val);
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_ini_file_parameter_boolean (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ pboolean default_val)
+{
+ pchar *val;
+ pboolean ret;
+
+ if ((val = pp_ini_file_find_parameter (file, section, key)) == NULL)
+ return default_val;
+
+ if (strcmp (val, "true") == 0 || strcmp (val, "TRUE") == 0)
+ ret = TRUE;
+ else if (strcmp (val, "false") == 0 || strcmp (val, "FALSE") == 0)
+ ret = FALSE;
+ else if (atoi (val) > 0)
+ ret = TRUE;
+ else
+ ret = FALSE;
+
+ p_free (val);
+
+ return ret;
+}
+
+P_LIB_API PList *
+p_ini_file_parameter_list (const PIniFile *file,
+ const pchar *section,
+ const pchar *key)
+{
+ PList *ret = NULL;
+ pchar *val, *str;
+ pchar buf[P_INI_FILE_MAX_LINE + 1];
+ psize len, buf_cnt;
+
+ if ((val = pp_ini_file_find_parameter (file, section, key)) == NULL)
+ return NULL;
+
+ len = strlen (val);
+
+ if (len < 3 || val[0] != '{' || val[len - 1] != '}') {
+ p_free (val);
+ return NULL;
+ }
+
+ /* Skip first brace '{' symbol */
+ str = val + 1;
+ buf[0] = '\0';
+ buf_cnt = 0;
+
+ while (*str && *str != '}') {
+ if (!isspace (* ((const puchar *) str)))
+ buf[buf_cnt++] = *str;
+ else {
+ buf[buf_cnt] = '\0';
+
+ if (buf_cnt > 0)
+ ret = p_list_append (ret, p_strdup (buf));
+
+ buf_cnt = 0;
+ }
+
+ ++str;
+ }
+
+ if (buf_cnt > 0) {
+ buf[buf_cnt] = '\0';
+ ret = p_list_append (ret, p_strdup (buf));
+ }
+
+ p_free (val);
+
+ return ret;
+}
diff --git a/3rdparty/plibsys/src/pinifile.h b/3rdparty/plibsys/src/pinifile.h
new file mode 100644
index 0000000..b2a2e3d
--- /dev/null
+++ b/3rdparty/plibsys/src/pinifile.h
@@ -0,0 +1,261 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2012-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pinifile.h
+ * @brief INI file parser
+ * @author Alexander Saprykin
+ *
+ * An INI file is usually used for storing configuration information. It
+ * consists of sections: every section starts with a line containing the name in
+ * square brackets (i.e. [section_name]). After that line all the following
+ * parameters will belong to that section until another section begins.
+ *
+ * Each section has a list of key-value pairs. Empty sections are not permitted
+ * (they will be skipped). Every key-value pair is represented with a line in
+ * the `key = value` format. If a section has several values with the same key
+ * the last one will be used. A value is parsed by the first in-order '='
+ * symbol. All the following '=' occurrences belong to the value.
+ *
+ * All symbols after '#' and ';' (even at the line ending) are the comments and
+ * wouldn't be read. If you want to use them in values take the value inside the
+ * "" or '' symbols. A section name line is not allowed to use the comment
+ * symbols after the section name in the square brackets itself.
+ *
+ * Integer values can be written in the usual form.
+ *
+ * Floating point values can be written in any commonly used notation (i.e. with
+ * the decimal point, in the exponential form using the 'e' character). The only
+ * valid decimal point symbol is the '.'. There is no locale dependency on the
+ * decimal point.
+ *
+ * Boolean values can be written in the form of 'true/false' or 'TRUE/FALSE', or
+ * simply '0/1'.
+ *
+ * Any value can be interpreted as a string at any moment. Actually all the
+ * values are stored internally as strings.
+ *
+ * A list of values can be stored between the '{}' symbols separated with
+ * spaces. The list only supports string values, so you should convert them to
+ * numbers manually. The list doesn't support strings with spaces - such strings
+ * will be splitted.
+ *
+ * To parse a file, create #PIniFile with p_ini_file_new() and then parse it
+ * with the p_ini_file_parse() routine.
+ *
+ * #PIniFile handles (skips) UTF-8/16/32 BOM characters (marks).
+ *
+ * Example of the INI file contents:
+ * @code
+ * [numeric_section]
+ * numeric_value_1 = 1234 # One type of the comment
+ * numeric_value_2 = 123 ; Comment is allowed here
+ *
+ * [floating_section]
+ * float_value_1 = 123.3e10
+ * float_value_2 = 123.19
+ *
+ * [boolean_section]
+ * boolean_value_1 = TRUE
+ * boolean_value_2 = 0
+ * boolean_value_3 = false
+ *
+ * [string_section]
+ * string_value_1 = "Test string"
+ * string_value_2 = 'Another test string'
+ *
+ * [list_section]
+ * list_value = {123 val 7654}
+ * @endcode
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PINIFILE_H
+#define PLIBSYS_HEADER_PINIFILE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <plist.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** INI file opaque data structure. */
+typedef struct PIniFile_ PIniFile;
+
+/**
+ * @brief Creates a new #PIniFile for parsing.
+ * @param path Path to a file to parse.
+ * @return Newly allocated #PIniFile in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PIniFile * p_ini_file_new (const pchar *path);
+
+/**
+ * @brief Frees memory and allocated resources of #PIniFile.
+ * @param file #PIniFile to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_ini_file_free (PIniFile *file);
+
+/**
+ * @brief Parses given #PIniFile.
+ * @param file #PIniFile file to parse.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_ini_file_parse (PIniFile *file,
+ PError **error);
+
+/**
+ * @brief Checks whether #PIniFile was already parsed or not.
+ * @param file #PIniFile to check.
+ * @return TRUE if the file was already parsed, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_ini_file_is_parsed (const PIniFile *file);
+
+/**
+ * @brief Gets all the sections from a given file.
+ * @param file #PIniFile to get the sections from. The @a file should be parsed
+ * before.
+ * @return #PList of section names.
+ * @since 0.0.1
+ * @note It's a caller responsibility to p_free() each returned string and to
+ * free the returned list with p_list_free().
+ */
+P_LIB_API PList * p_ini_file_sections (const PIniFile *file);
+
+/**
+ * @brief Gets all the keys from a given section.
+ * @param file #PIniFile to get the keys from. The @a file should be parsed
+ * before.
+ * @param section Section name to get the keys from.
+ * @return #PList of key names.
+ * @since 0.0.1
+ * @note It's a caller responsibility to p_free() each returned string and to
+ * free the returned list with p_list_free().
+ */
+P_LIB_API PList * p_ini_file_keys (const PIniFile *file,
+ const pchar *section);
+
+/**
+ * @brief Checks whether a key exists.
+ * @param file #PIniFile to check in. The @a file should be parsed before.
+ * @param section Section to check the key in.
+ * @param key Key to check.
+ * @return TRUE if @a key exists, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_ini_file_is_key_exists (const PIniFile *file,
+ const pchar *section,
+ const pchar *key);
+
+/**
+ * @brief Gets specified parameter's value as a string.
+ * @param file #PIniFile to get the value from. The @a file should be parsed
+ * before.
+ * @param section Section to get the value from.
+ * @param key Key to get the value from.
+ * @param default_val Default value to return if no specified key exists.
+ * @return Key's value in case of success, @a default_value otherwise.
+ * @since 0.0.1
+ * @note It's a caller responsibility to p_free() the returned string after
+ * usage.
+ */
+P_LIB_API pchar * p_ini_file_parameter_string (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ const pchar *default_val);
+
+/**
+ * @brief Gets specified parameter's value as an integer.
+ * @param file #PIniFile to get the value from. The @a file should be parsed
+ * before.
+ * @param section Section to get the value from.
+ * @param key Key to get the value from.
+ * @param default_val Default value to return if no specified key exists.
+ * @return Key's value in case of success, @a default_value otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pint p_ini_file_parameter_int (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ pint default_val);
+
+/**
+ * @brief Gets specified parameter's value as a floating point.
+ * @param file #PIniFile to get the value from. The @a file should be parsed
+ * before.
+ * @param section Section to get the value from.
+ * @param key Key to get the value from.
+ * @param default_val Default value to return if no specified key exists.
+ * @return Key's value in case of success, @a default_value otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API double p_ini_file_parameter_double (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ double default_val);
+/**
+ * @brief Gets specified parameter's value as a boolean.
+ * @param file #PIniFile to get the value from. The @a file should be parsed
+ * before.
+ * @param section Section to get the value from.
+ * @param key Key to get the value from.
+ * @param default_val Default value to return if no specified key exists.
+ * @return Key's value in case of success, @a default_value otherwise.
+ * @since 0.0.1
+ */
+
+P_LIB_API pboolean p_ini_file_parameter_boolean (const PIniFile *file,
+ const pchar *section,
+ const pchar *key,
+ pboolean default_val);
+
+/**
+ * @brief Gets specified parameter's value as a list of strings separated with
+ * the spaces or tabs.
+ * @param file #PIniFile to get the value from. The @a file should be parsed
+ * before.
+ * @param section Section to get the value from.
+ * @param key Key to get the value from.
+ * @return #PList of strings. NULL will be returned if no parameter with the
+ * given name exists.
+ * @since 0.0.1
+ * @note It's a caller responsibility to p_free() each returned string and to
+ * free the returned list with p_list_free().
+ */
+P_LIB_API PList * p_ini_file_parameter_list (const PIniFile *file,
+ const pchar *section,
+ const pchar *key);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PINIFILE_H */
diff --git a/3rdparty/plibsys/src/pipc-private.h b/3rdparty/plibsys/src/pipc-private.h
new file mode 100644
index 0000000..312d378
--- /dev/null
+++ b/3rdparty/plibsys/src/pipc-private.h
@@ -0,0 +1,76 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PIPC_PRIVATE_H
+#define PLIBSYS_HEADER_PIPC_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+
+P_BEGIN_DECLS
+
+#if !defined (P_OS_WIN) && !defined (P_OS_OS2)
+/**
+ * @brief Gets a temporary directory on UNIX systems.
+ * @return Temporary directory.
+ */
+pchar * p_ipc_unix_get_temp_dir (void);
+
+/* Create file for System V IPC, if needed
+ * Returns: -1 = error, 0 = file successfully created, 1 = file already exists */
+/**
+ * @brief Creates a file for System V IPC usage.
+ * @param file_name File name to create.
+ * @return -1 in case of error, 0 if all was OK, and 1 if the file already
+ * exists.
+ */
+pint p_ipc_unix_create_key_file (const pchar *file_name);
+
+/**
+ * @brief Wrapps the ftok() UNIX call for a unique IPC key.
+ * @param file_name File name for ftok() call.
+ * @return Key in case of success, -1 otherwise.
+ */
+pint p_ipc_unix_get_ftok_key (const pchar *file_name);
+#endif /* !P_OS_WIN && !P_OS_OS2 */
+
+/**
+ * @brief Generates a platform independent key for IPC usage, an object name for
+ * Windows and a file name to use with ftok () for UNIX-like systems.
+ * @param name Object name.
+ * @param posix TRUE if the key will be used for the POSIX IPC calls, otherwise
+ * FALSE. This parameter is not used on the Windows platform.
+ * @return Platform independent key for IPC usage.
+ */
+pchar * p_ipc_get_platform_key (const pchar *name,
+ pboolean posix);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PIPC_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/pipc.c b/3rdparty/plibsys/src/pipc.c
new file mode 100644
index 0000000..60093ee
--- /dev/null
+++ b/3rdparty/plibsys/src/pipc.c
@@ -0,0 +1,178 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pcryptohash.h"
+#include "pstring.h"
+#include "psysclose-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined (P_OS_WIN) && !defined (P_OS_OS2) && !defined (P_OS_AMIGA)
+# include <unistd.h>
+# include <errno.h>
+# include <fcntl.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+# include <sys/ipc.h>
+#endif
+
+#if !defined (P_OS_WIN) && !defined (P_OS_OS2) && !defined (P_OS_AMIGA)
+pchar *
+p_ipc_unix_get_temp_dir (void)
+{
+ pchar *str, *ret;
+ psize len;
+
+#ifdef P_tmpdir
+ if (strlen (P_tmpdir) > 0)
+ str = p_strdup (P_tmpdir);
+ else
+ return p_strdup ("/tmp/");
+#else
+ const pchar *tmp_env;
+
+ tmp_env = getenv ("TMPDIR");
+
+ if (tmp_env != NULL)
+ str = p_strdup (tmp_env);
+ else
+ return p_strdup ("/tmp/");
+#endif /* P_tmpdir */
+
+ /* Now we need to ensure that we have only the one trailing slash */
+ len = strlen (str);
+ while (*(str + --len) == '/')
+ ;
+ *(str + ++len) = '\0';
+
+ /* len + / + zero symbol */
+ if (P_UNLIKELY ((ret = p_malloc0 (len + 2)) == NULL)) {
+ p_free (str);
+ return NULL;
+ }
+
+ strcpy (ret, str);
+ strcat (ret, "/");
+
+ return ret;
+}
+
+/* Create file for System V IPC, if needed
+ * Returns: -1 = error, 0 = file successfully created, 1 = file already exists */
+pint
+p_ipc_unix_create_key_file (const pchar *file_name)
+{
+ pint fd;
+
+ if (P_UNLIKELY (file_name == NULL))
+ return -1;
+
+ if ((fd = open (file_name, O_CREAT | O_EXCL | O_RDONLY, 0640)) == -1)
+ /* file already exists */
+ return (errno == EEXIST) ? 1 : -1;
+ else
+ return p_sys_close (fd);
+}
+
+pint
+p_ipc_unix_get_ftok_key (const pchar *file_name)
+{
+ struct stat st_info;
+
+ if (P_UNLIKELY (file_name == NULL))
+ return -1;
+
+ if (P_UNLIKELY (stat (file_name, &st_info) == -1))
+ return -1;
+
+ return ftok (file_name, 'P');
+}
+#endif /* !P_OS_WIN && !P_OS_OS2 && !P_OS_AMIGA */
+
+/* Returns a platform-independent key for IPC usage, object name for Windows and
+ * a file name to use with ftok () for UNIX-like systems */
+pchar *
+p_ipc_get_platform_key (const pchar *name, pboolean posix)
+{
+ PCryptoHash *sha1;
+ pchar *hash_str;
+
+#if defined (P_OS_WIN) || defined (P_OS_OS2) || defined (P_OS_AMIGA)
+ P_UNUSED (posix);
+#else
+ pchar *path_name, *tmp_path;
+#endif
+
+ if (P_UNLIKELY (name == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((sha1 = p_crypto_hash_new (P_CRYPTO_HASH_TYPE_SHA1)) == NULL))
+ return NULL;
+
+ p_crypto_hash_update (sha1, (const puchar *) name, strlen (name));
+
+ hash_str = p_crypto_hash_get_string (sha1);
+ p_crypto_hash_free (sha1);
+
+ if (P_UNLIKELY (hash_str == NULL))
+ return NULL;
+
+#if defined (P_OS_WIN) || defined (P_OS_OS2) || defined (P_OS_AMIGA)
+ return hash_str;
+#else
+ if (posix) {
+ /* POSIX semaphores which are named kinda like '/semname'.
+ * Some implementations of POSIX semaphores has restriction for
+ * the name as of max 14 characters, best to use this limit */
+ if (P_UNLIKELY ((path_name = p_malloc0 (15)) == NULL)) {
+ p_free (hash_str);
+ return NULL;
+ }
+
+ strcpy (path_name, "/");
+ strncat (path_name, hash_str, 13);
+ } else {
+ tmp_path = p_ipc_unix_get_temp_dir ();
+
+ /* tmp dir + filename + zero symbol */
+ path_name = p_malloc0 (strlen (tmp_path) + strlen (hash_str) + 1);
+
+ if (P_UNLIKELY ((path_name) == NULL)) {
+ p_free (tmp_path);
+ p_free (hash_str);
+ return NULL;
+ }
+
+ strcpy (path_name, tmp_path);
+ strcat (path_name, hash_str);
+ p_free (tmp_path);
+ }
+
+ p_free (hash_str);
+ return path_name;
+#endif
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-amiga.c b/3rdparty/plibsys/src/plibraryloader-amiga.c
new file mode 100644
index 0000000..463e350
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-amiga.c
@@ -0,0 +1,583 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ * Copyright (C) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Path conversion code was taken and adopted from clib2 project:
+ * https://github.com/adtools/clib2
+ *
+ * This part of code is distributed under the BSD-3-Clause license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Neither the name of Olaf Barthel nor the names of contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+#include <string.h>
+
+#include <proto/dos.h>
+#include <proto/elf.h>
+
+#if defined (__CLIB2__)
+# include <dos.h>
+#elif defined (__NEWLIB__)
+# include <amiga_platform.h>
+#endif
+
+typedef APTR plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+ Elf32_Error last_error;
+};
+
+static Elf32_Handle pp_library_loader_elf_root = NULL;
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+static pint pp_library_loader_translate_path (const pchar *in, pchar *out, psize out_len);
+
+/*
+ * The following patterns must translate properly:
+ *
+ * foo/
+ * ///
+ * foo//bar
+ * foo//bar//baz
+ * ./foo
+ * ././foo
+ * foo/./baz
+ * foo/./bar/./baz
+ * foo/./././bar
+ * foo/.
+ * /.
+ * /tmp
+ * /tmp/foo
+ * /dev/null
+ * /dev/null/foo
+ * /dev/nullX
+ * /foo
+ * /foo/
+ * /foo/bar
+ * /foo/bar/baz
+ * foo/../bar
+ * foo/bar/../../baz
+ * foo/bar/..
+ * ../foo
+ * ../../foo
+ * .
+ * ..
+ */
+
+static pint
+pp_library_loader_translate_path (const pchar *in, pchar *out, psize out_len)
+{
+ pchar volume_name[MAXPATHLEN];
+ psize len, volume_name_len;
+ pint i, j;
+
+ len = strlen (in);
+
+ if (out_len < MAXPATHLEN || len > MAXPATHLEN)
+ return -1;
+
+ strcpy (out, in);
+
+ /* Just copy is path is already an Amiga one */
+
+ if (strchr (in, ':') != NULL)
+ return 0;
+
+ in = out;
+
+ /* Strip neighbouring slashes: ('foo//bar' -> 'foo/bar').
+ * The "//" pattern in a Unix file name is apparently harmless,
+ * but on AmigaDOS it has a very definite meaning. */
+
+ if (len > 2) {
+ pboolean have_double_slash = FALSE;
+
+ for (i = 0; i < len - 1; ++i) {
+ if (in[i] == '/' && in[i + 1] == '/') {
+ have_double_slash = TRUE;
+ break;
+ }
+ }
+
+ if (have_double_slash) {
+ pboolean have_slash;
+ pchar c;
+
+ have_slash = FALSE;
+
+ for (i = j = 0; i < len; ++i) {
+ c = in[i];
+
+ if (c == '/') {
+ if (!have_slash)
+ out[j++] = c;
+
+ have_slash = TRUE;
+ } else {
+ out[j++] = c;
+ have_slash = FALSE;
+ }
+ }
+
+ len = j;
+ out[len] = '\0';
+ }
+ }
+
+ /* Strip trailing slashes ('foo/' -> 'foo'). A leading '/' must
+ * be preserved, though ('///' -> '/'). */
+
+ if(len > 1) {
+ psize num_trailing_slashes = 0;
+
+ while ((num_trailing_slashes < len - 1) && (in[len - (num_trailing_slashes + 1)] == '/'))
+ num_trailing_slashes++;
+
+ if (num_trailing_slashes > 0) {
+ len -= num_trailing_slashes;
+ out[len] = '\0';
+ }
+ }
+
+ /* Ditch all leading './' ('./foo' -> 'foo'). */
+
+ while (len > 2 && out[0] == '.' && out[1] == '/') {
+ len -= 2;
+ memmove (out, &out[2], len);
+ out[len] = '\0';
+ }
+
+ /* Ditch all embedded '/./' ('foo/./bar' -> 'foo/bar', 'foo/././bar' -> 'foo/bar'). */
+
+ if (len > 2) {
+ pboolean have_slash_dot_slash = FALSE;
+
+ for (i = j = 0; i < len - 2; ++i) {
+ if(in[i] == '/' && in[i + 1] == '.' && in[i + 2] == '/') {
+ have_slash_dot_slash = TRUE;
+ break;
+ }
+ }
+
+ if (have_slash_dot_slash) {
+ for (i = j = 0; i < len; ++i) {
+ while (i < len - 2 && in[i] == '/' && in[i + 1] == '.' && in[i + 2] == '/')
+ i += 2;
+
+ if (i < len)
+ out[j++] = in[i];
+ }
+
+ len = j;
+ out[len] = '\0';
+ }
+ }
+
+ /* Special case: the path name may end with "/." signifying that the
+ * directory itself is requested ('foo/.' -> 'foo'). */
+
+ if (len >= 2 && strncmp (&in[len - 2], "/.", 2) == 0) {
+ /* If it's just '/.' then it's really '/'. */
+ if (len == 2) {
+ strcpy (out, "/");
+ len = 1;
+ } else {
+ len -= 2;
+ out[len] = '\0';
+ }
+ }
+
+ /* Check for absolute path. */
+
+ if (in[0] == '/') {
+ /* OK, so this is an absolute path. We begin by checking
+ * for a few special cases, the first being a reference
+ * to "/tmp". */
+ if ((strncmp (in, "/tmp", 4) == 0) && (in[4] == '/' || len == 4)) {
+ if (in[4] == '/') {
+ /* Convert "/tmp/foo" to "T:foo". */
+ memmove (&out[2], &in[5], len - 5);
+ memmove (out, "T:", 2);
+
+ len -= 3;
+ } else {
+ /* Convert "/tmp" to "T:". */
+ strcpy (out, "T:");
+
+ len = 2;
+ }
+
+ out[len] = '\0';
+ } else if ((strncmp (in, "/dev/null", 9)) == 0 && (len == 9 || in[9] == '/')) {
+ strcpy (out, "NIL:");
+ len = 4;
+ } else {
+ psize path_name_start = 0;
+ volume_name_len = 0;
+
+ /* Find out how long the first component of the absolute path is. */
+ for (i = 1; i <= len; ++i) {
+ if (i == len || in[i] == '/') {
+ volume_name_len = i - 1;
+
+ /* Is there anything following the path name? */
+ if (i < len)
+ path_name_start = i + 1;
+
+ break;
+ }
+ }
+
+ /* Copy the first component and attach a colon. "/foo" becomes "foo:". */
+ memmove (out, &in[1], volume_name_len);
+ out[volume_name_len++] = ':';
+
+ /* Now add the finishing touches. "/foo/bar" finally
+ * becomes "foo:bar" and "/foo" becomes "foo:". */
+ if (path_name_start > 0) {
+ memmove (&out[volume_name_len], &in[path_name_start], len - path_name_start);
+
+ len--;
+ }
+
+ out[len] = '\0';
+ }
+ }
+
+ /* Extract and remove the volume name from the path. We
+ * are going to need it later. */
+
+ volume_name_len = 0;
+
+ for (i = 0; i < len; ++i) {
+ if (in[i] == ':') {
+ /* Look for extra colon characters embedded in the name
+ * (as in "foo/bar:baz") which really don't belong here. */
+ for (j = 0 ; j < i ; j++) {
+ if(in[j] == '/')
+ return -1;
+ }
+
+ volume_name_len = i + 1;
+ len -= volume_name_len;
+
+ memmove (volume_name, in, volume_name_len);
+ memmove (out, &out[volume_name_len], len);
+
+ out[len] = '\0';
+
+ break;
+ }
+ }
+
+ /* Look for extra colon characters embedded in the name
+ * (as in "foo:bar:baz") which really don't belong here. */
+
+ for (i = 0; i < len; ++i) {
+ if (in[i] == ':')
+ return -1;
+ }
+
+ /* Now parse the path name and replace all embedded '..' with
+ * the AmigaDOS counterparts ('foo/../bar' -> 'foo//bar'). */
+
+ if (len > 3) {
+ pboolean have_slash_dot_dot_slash = FALSE;
+
+ for (i = j = 0; i < len - 3; ++i) {
+ if (in[i] == '/' && in[i + 1] == '.' && in[i + 2] == '.' && in[i + 3] == '/') {
+ have_slash_dot_dot_slash = TRUE;
+ break;
+ }
+ }
+
+ if (have_slash_dot_dot_slash) {
+ pboolean have_before = FALSE;
+
+ for (i = j = 0; i < len; ++i) {
+ if(i < len - 3 && in[i] == '/' && in[i + 1] == '.' && in[i + 2] == '.' && in[i + 3] == '/') {
+ out[j++] = in[i];
+
+ if (have_before)
+ out[j++] = '/';
+
+ i += 2;
+
+ have_before = TRUE;
+ } else {
+ have_before = FALSE;
+ out[j++] = in[i];
+ }
+ }
+
+ len = j;
+ out[len] = '\0';
+ }
+ }
+
+ /* Translate a trailing '/..' to '//' */
+
+ if (len >= 3 && strncmp (&in[len - 3], "/..", 3) == 0) {
+ len -= 2;
+ out[len++] = '/';
+ out[len] = '\0';
+ }
+
+ /* Translate a leading '../' ('../foo' -> '/foo') */
+
+ if (len >= 3 && strncmp (in, "../", 3) == 0) {
+ memmove (out, &in[2], len - 2);
+
+ len -= 2;
+ out[len] = '\0';
+ }
+
+ /* Translate the '..' ('..' -> '/') */
+
+ if (len == 2 && strncmp (in, "..", 2) == 0) {
+ strcpy (out, "/");
+
+ len = 1;
+ }
+
+ /* Translate the '.' ('.' -> '') */
+
+ if (len == 1 && in[0] == '.') {
+ strcpy (out, "");
+
+ len = 0;
+ }
+
+ /* Now put it all together again. */
+
+ if(volume_name_len > 0) {
+ memmove (&out[volume_name_len], in, len);
+ memmove (out, volume_name, volume_name_len);
+
+ len += volume_name_len;
+ out[len] = '\0';
+ }
+
+ return 0;
+}
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ IElf->DLClose (pp_library_loader_elf_root, handle);
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle = NULL;
+ pchar path_buffer[MAXPATHLEN];
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+ if (pp_library_loader_elf_root == NULL) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: shared library subsystem is not initialized");
+ return NULL;
+ }
+
+ if (strlen (path) >= MAXPATHLEN) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: too long file path or name");
+ return NULL;
+ }
+
+ if (pp_library_loader_translate_path (path, path_buffer, MAXPATHLEN) != 0) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to convert to UNIX path");
+ return NULL;
+ }
+
+ path = path_buffer;
+
+ handle = IElf->DLOpen (pp_library_loader_elf_root, (CONST_STRPTR) path, ELF32_RTLD_LOCAL);
+
+ if (P_UNLIKELY (handle == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: DLOpen() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+ loader->last_error = ELF32_NO_ERROR;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ APTR func_addr = NULL;
+
+ if (P_UNLIKELY (loader == NULL || sym == NULL || loader->handle == NULL))
+ return NULL;
+
+ if (pp_library_loader_elf_root == NULL) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: shared library subsystem is not initialized");
+ return NULL;
+ }
+
+ loader->last_error = IElf->DLSym (pp_library_loader_elf_root,
+ loader->handle,
+ (CONST_STRPTR) sym,
+ &func_addr);
+
+ return (PFuncAddr) func_addr;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return NULL;
+
+ switch (loader->last_error) {
+ case ELF32_NO_ERROR:
+ return NULL;
+ case ELF32_OUT_OF_MEMORY:
+ return p_strdup ("Out of memory");
+ case ELF32_INVALID_HANDLE:
+ return p_strdup ("Invalid resource handler");
+ case ELF32_NO_MORE_RELOCS:
+ return p_strdup ("No more relocations left");
+ case ELF32_SECTION_NOT_LOADED:
+ return p_strdup ("Section not loaded");
+ case ELF32_UNKNOWN_RELOC:
+ return p_strdup ("Unknown relocation");
+ case ELF32_READ_ERROR:
+ return p_strdup ("Read error");
+ case ELF32_INVALID_SDA_BASE:
+ return p_strdup ("Invalid SDA base");
+ case ELF32_SYMBOL_NOT_FOUND:
+ return p_strdup ("Symbol not found");
+ case ELF32_INVALID_NAME:
+ return p_strdup ("Invalid procedure name");
+ case ELF32_REQUIRED_OBJECT_MISSING:
+ return p_strdup ("Required object is missing");
+ default:
+ return p_strdup ("Unknown error");
+ }
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return TRUE;
+}
+
+void
+p_library_loader_init (void)
+{
+ BPTR segment_list;
+ Elf32_Handle elf_handle;
+
+ if (pp_library_loader_elf_root != NULL)
+ return;
+
+ segment_list = IDOS->GetProcSegList (NULL, GPSLF_RUN);
+
+ if (P_UNLIKELY (segment_list == 0)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_init: GetProcSegList() failed");
+ return;
+ }
+
+ if (P_UNLIKELY (IDOS->GetSegListInfoTags (segment_list,
+ GSLI_ElfHandle,
+ &elf_handle,
+ TAG_DONE) != 1)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_init: GetSegListInfoTags() failed");
+ return;
+ }
+
+ if (P_UNLIKELY (elf_handle == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_init: failed to finf proper GSLI_ElfHandle");
+ return;
+ }
+
+ pp_library_loader_elf_root = IElf->OpenElfTags (OET_ElfHandle, elf_handle, TAG_DONE);
+
+ if (P_UNLIKELY (pp_library_loader_elf_root == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_init: OpenElfTags() failed");
+ return;
+ }
+}
+
+void
+p_library_loader_shutdown (void)
+{
+ if (pp_library_loader_elf_root == NULL)
+ return;
+
+ IElf->CloseElfTags (pp_library_loader_elf_root, CET_ReClose, TRUE, TAG_DONE);
+
+ pp_library_loader_elf_root = NULL;
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-beos.c b/3rdparty/plibsys/src/plibraryloader-beos.c
new file mode 100644
index 0000000..403f7f4
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-beos.c
@@ -0,0 +1,142 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+#include <be/kernel/image.h>
+
+typedef image_id plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+ status_t last_status;
+};
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ if (P_UNLIKELY (unload_add_on (handle) != B_OK))
+ P_ERROR ("PLibraryLoader::pp_library_loader_clean_handle: unload_add_on() failed");
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle;
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+ if (P_UNLIKELY ((handle = load_add_on (path)) == B_ERROR)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: load_add_on() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+ loader->last_status = B_OK;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ ppointer location = NULL;
+ status_t status;
+
+ if (P_UNLIKELY (loader == NULL || sym == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((status = get_image_symbol (loader->handle,
+ (pchar *) sym,
+ B_SYMBOL_TYPE_ANY,
+ &location)) != B_OK)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_get_symbol: get_image_symbol() failed");
+ loader->last_status = status;
+ return NULL;
+ }
+
+ loader->last_status = B_OK;
+
+ return (PFuncAddr) location;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ if (loader == NULL)
+ return NULL;
+
+ switch (loader->last_status) {
+ case B_OK:
+ return NULL;
+ case B_BAD_IMAGE_ID:
+ return p_strdup ("Image handler doesn't identify an existing image");
+ case B_BAD_INDEX:
+ return p_strdup ("Invalid symbol index");
+ default:
+ return p_strdup ("Unknown error");
+ }
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return TRUE;
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-none.c b/3rdparty/plibsys/src/plibraryloader-none.c
new file mode 100644
index 0000000..aab6d87
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-none.c
@@ -0,0 +1,75 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibraryloader.h"
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ P_ERROR ("PLibraryLoader::p_library_loader_new: not implemented");
+ return NULL;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ P_UNUSED (loader);
+ P_UNUSED (sym);
+
+ P_ERROR ("PLibraryLoader::p_library_loader_get_symbol: not implemented");
+ return NULL;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ P_UNUSED (loader);
+ P_ERROR ("PLibraryLoader::p_library_loader_free: not implemented");
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ P_UNUSED (loader);
+
+ P_ERROR ("PLibraryLoader::p_library_loader_get_last_error: not implemented");
+ return NULL;
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return FALSE;
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-os2.c b/3rdparty/plibsys/src/plibraryloader-os2.c
new file mode 100644
index 0000000..0f6c95d
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-os2.c
@@ -0,0 +1,155 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+#define INCL_DOSMODULEMGR
+#define INCL_DOSERRORS
+#include <os2.h>
+
+typedef HMODULE plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+ APIRET last_error;
+};
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ APIRET ulrc;
+
+ while ((ulrc = DosFreeModule (handle)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR))
+ P_ERROR ("PLibraryLoader::pp_library_loader_clean_handle: DosFreeModule() failed");
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle = NULLHANDLE;
+ UCHAR load_err[256];
+ APIRET ulrc;
+
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+ while ((ulrc = DosLoadModule ((PSZ) load_err,
+ sizeof (load_err),
+ (PSZ) path,
+ (PHMODULE) &handle)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: DosLoadModule() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+ loader->last_error = NO_ERROR;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ PFN func_addr = NULL;
+ APIRET ulrc;
+
+ if (P_UNLIKELY (loader == NULL || sym == NULL || loader->handle == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ulrc = DosQueryProcAddr (loader->handle, 0, (PSZ) sym, &func_addr)) != NO_ERROR)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_get_symbol: DosQueryProcAddr() failed");
+ loader->last_error = ulrc;
+ return NULL;
+ }
+
+ loader->last_error = NO_ERROR;
+
+ return (PFuncAddr) func_addr;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ if (loader == NULL)
+ return NULL;
+
+ switch (loader->last_error) {
+ case NO_ERROR:
+ return NULL;
+ case ERROR_INVALID_HANDLE:
+ return p_strdup ("Invalid resource handler");
+ case ERROR_INVALID_NAME:
+ return p_strdup ("Invalid procedure name");
+ default:
+ return p_strdup ("Unknown error");
+ }
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return TRUE;
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-posix.c b/3rdparty/plibsys/src/plibraryloader-posix.c
new file mode 100644
index 0000000..75ef8ed
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-posix.c
@@ -0,0 +1,148 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+#include <dlfcn.h>
+
+/* FreeBSD may cause a segfault: https://reviews.freebsd.org/D5112,
+ * DragonFlyBSD as well, so we need to check a file size before calling dlopen()
+ */
+#if defined (P_OS_FREEBSD) || defined (P_OS_DRAGONFLY)
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+typedef ppointer plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+};
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ if (P_UNLIKELY (dlclose (handle) != 0))
+ P_ERROR ("PLibraryLoader::pp_library_loader_clean_handle: dlclose() failed");
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle;
+#if defined (P_OS_FREEBSD) || defined (P_OS_DRAGONFLY)
+ struct stat stat_buf;
+#endif
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+#if defined (P_OS_FREEBSD) || defined (P_OS_DRAGONFLY)
+ if (P_UNLIKELY (stat (path, &stat_buf) != 0)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: stat() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (stat_buf.st_size == 0)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: unable to handle zero-size file");
+ return NULL;
+ }
+#endif
+
+ if (P_UNLIKELY ((handle = dlopen (path, RTLD_NOW)) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: dlopen() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ if (P_UNLIKELY (loader == NULL || sym == NULL || loader->handle == NULL))
+ return NULL;
+
+ return (PFuncAddr) dlsym (loader->handle, sym);
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ pchar *res = NULL;
+ pchar *msg;
+
+ P_UNUSED (loader);
+
+ msg = dlerror ();
+
+ if (msg != NULL)
+ res = p_strdup (msg);
+
+ return res;
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return TRUE;
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-shl.c b/3rdparty/plibsys/src/plibraryloader-shl.c
new file mode 100644
index 0000000..8129697
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-shl.c
@@ -0,0 +1,140 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+#include <dl.h>
+#include <errno.h>
+#include <string.h>
+
+typedef shl_t plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+ int last_error;
+};
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ if (P_UNLIKELY (shl_unload (handle) != 0))
+ P_ERROR ("PLibraryLoader::pp_library_loader_clean_handle: shl_unload() failed");
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle;
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+ if (P_UNLIKELY ((handle = shl_load (path, BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH, 0)) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: shl_load() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+ loader->last_error = 0;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ PFuncAddr func_addr = NULL;
+
+ if (P_UNLIKELY (loader == NULL || sym == NULL || loader->handle == NULL))
+ return NULL;
+
+ if (P_UNLIKELY (shl_findsym (&loader->handle, sym, TYPE_UNDEFINED, (ppointer) &func_addr) != 0)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_get_symbol: shl_findsym() failed");
+ loader->last_error = (errno == 0 ? -1 : errno);
+ return NULL;
+ }
+
+ loader->last_error = 0;
+
+ return func_addr;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ if (loader == NULL)
+ return NULL;
+
+ if (loader->last_error == 0)
+ return NULL;
+ else if (loader->last_error == -1)
+ return p_strdup ("Failed to find a symbol");
+ else
+ return p_strdup (strerror (loader->last_error));
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+#if defined (P_OS_HPUX) && defined (P_CPU_HPPA) && (PLIBSYS_SIZEOF_VOID_P == 4)
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader-win.c b/3rdparty/plibsys/src/plibraryloader-win.c
new file mode 100644
index 0000000..80c5aba
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader-win.c
@@ -0,0 +1,140 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pfile.h"
+#include "plibraryloader.h"
+#include "pmem.h"
+#include "pstring.h"
+
+typedef HINSTANCE plibrary_handle;
+
+struct PLibraryLoader_ {
+ plibrary_handle handle;
+};
+
+static void pp_library_loader_clean_handle (plibrary_handle handle);
+
+static void
+pp_library_loader_clean_handle (plibrary_handle handle)
+{
+ if (P_UNLIKELY (!FreeLibrary (handle)))
+ P_ERROR ("PLibraryLoader::pp_library_loader_clean_handle: FreeLibrary() failed");
+}
+
+P_LIB_API PLibraryLoader *
+p_library_loader_new (const pchar *path)
+{
+ PLibraryLoader *loader = NULL;
+ plibrary_handle handle;
+
+ if (!p_file_is_exists (path))
+ return NULL;
+
+ if (P_UNLIKELY ((handle = LoadLibraryA (path)) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: LoadLibraryA() failed");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) {
+ P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory");
+ pp_library_loader_clean_handle (handle);
+ return NULL;
+ }
+
+ loader->handle = handle;
+
+ return loader;
+}
+
+P_LIB_API PFuncAddr
+p_library_loader_get_symbol (PLibraryLoader *loader, const pchar *sym)
+{
+ PFuncAddr ret_sym = NULL;
+
+ if (P_UNLIKELY (loader == NULL || sym == NULL || loader->handle == NULL))
+ return NULL;
+
+ ret_sym = (PFuncAddr) GetProcAddress (loader->handle, sym);
+
+ return ret_sym;
+}
+
+P_LIB_API void
+p_library_loader_free (PLibraryLoader *loader)
+{
+ if (P_UNLIKELY (loader == NULL))
+ return;
+
+ pp_library_loader_clean_handle (loader->handle);
+
+ p_free (loader);
+}
+
+P_LIB_API pchar *
+p_library_loader_get_last_error (PLibraryLoader *loader)
+{
+ pchar *res = NULL;
+ DWORD err_code;
+ LPVOID msg_buf;
+
+ P_UNUSED (loader);
+
+ err_code = p_error_get_last_system ();
+
+ if (err_code == 0)
+ return NULL;
+
+ if (P_LIKELY (FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err_code,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR) &msg_buf,
+ 0,
+ NULL) != 0)) {
+ res = p_strdup ((pchar *) msg_buf);
+ LocalFree (msg_buf);
+ }
+
+ return res;
+}
+
+P_LIB_API pboolean
+p_library_loader_is_ref_counted (void)
+{
+ return TRUE;
+}
+
+void
+p_library_loader_init (void)
+{
+}
+
+void
+p_library_loader_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/plibraryloader.h b/3rdparty/plibsys/src/plibraryloader.h
new file mode 100644
index 0000000..d44bef2
--- /dev/null
+++ b/3rdparty/plibsys/src/plibraryloader.h
@@ -0,0 +1,155 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file plibraryloader.h
+ * @brief Shared library loader
+ * @author Alexander Saprykin
+ *
+ * All modern operating systems support dynamic loadable objects. Such objects
+ * are compiled with special flags and can be loaded by other programs and
+ * libraries later at the runtime. These loadable objects often called as the
+ * shared libraries, though some platforms even allow to treat the program
+ * binary as a loadable object, too.
+ *
+ * When the program is linked with a shared library its dependency would be
+ * resolved by the operating system automatically before starting the program.
+ * But in some circumstances you may need to load a shared library object
+ * explicitly (i.e. implementing a plugin subsystem, checking for API
+ * availability).
+ *
+ * All functions and variables which a shared library is exporting are called
+ * symbols. Usually only the exported symbols are available from outside the
+ * shared library. Actually all those symbols represent a library API.
+ *
+ * Use p_library_loader_new() to load a shared library and
+ * p_library_loader_get_symbol() to retrieve a pointer to a symbol within it.
+ * Close the library after usage with p_library_loader_free().
+ *
+ * Please note the following platform specific differences:
+ *
+ * - HP-UX doesn't support loading libraries containing TLS and built with
+ * static TLS model. The same rule applies to any library used as dependency.
+ * HP-UX on 32-bit PA-RISC systems doesn't support reference counting for loaded
+ * libraries when using shl_* family of functions (always removes all library
+ * references on unload).
+ *
+ * - On OpenVMS only shareable images (linked with /SHAREABLE) can be used for
+ * dynamic symbol resolving. Usually they have .EXE extension.
+ *
+ * - BeOS supports dynamic loading for add-ons only. It is also possible to
+ * load the same library several times independently (not like a traditional
+ * shared library).
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PLIBRARYLOADER_H
+#define PLIBSYS_HEADER_PLIBRARYLOADER_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Opaque data structure to handle a shared library. */
+typedef struct PLibraryLoader_ PLibraryLoader;
+
+/** Pointer to a function address. */
+typedef void (*PFuncAddr) (void);
+
+/**
+ * @brief Loads a shared library.
+ * @param path Path to the shared library file.
+ * @return Pointer to #PLibraryLoader in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * If you are loading the already loaded shared library, an operating system
+ * increments corresponding reference count and decrements it after freeing
+ * #PLibraryLoader, thus the shared library would be unloaded from the address
+ * space only when the counter becomes zero.
+ */
+P_LIB_API PLibraryLoader * p_library_loader_new (const pchar *path);
+
+/**
+ * @brief Gets a pointer to a symbol in the loaded shared library.
+ * @param loader Pointer to the loaded shared library handle.
+ * @param sym Name of the symbol.
+ * @return Pointer to the symbol in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * Since the symbol may have a NULL value, the returned NULL value from this
+ * call actually doesn't mean the failed result. You can additionally check the
+ * error result using p_library_loader_get_last_error().
+ */
+P_LIB_API PFuncAddr p_library_loader_get_symbol (PLibraryLoader *loader,
+ const pchar *sym);
+
+/**
+ * @brief Frees memory and allocated resources of #PLibraryLoader.
+ * @param loader #PLibraryLoader object to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_library_loader_free (PLibraryLoader *loader);
+
+/**
+ * @brief Gets the last occurred error.
+ * @param loader #PLibraryLoader object to get error for.
+ * @return Human readable error string in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @version 0.0.3 @p loader parameter was added.
+ * @note Caller takes ownership of the returned string.
+ *
+ * The NULL result may indicate that no error was occurred since the last call.
+ *
+ * Different operating systems have different behavior on error indicating.
+ * Some systems reset an error status before the call, some do not. Some
+ * systems write the successful call result (usually zero) to the error status,
+ * thus resetting an error from the previous call.
+ *
+ * Some operating systems may return last error even if library handler was not
+ * created. In that case try to pass NULL value as a parameter.
+ */
+P_LIB_API pchar * p_library_loader_get_last_error (PLibraryLoader *loader);
+
+/**
+ * @brief Checks whether library loading subsystem uses reference counting.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.3
+ *
+ * When reference counting is supported, the same shared library can be opened
+ * several times, but it would be completely unloaded from the memory only when
+ * the last reference to it is removed.
+ *
+ * @note For now, only HP-UX on 32-bit PA-RISC systems with shl_* model doesn't
+ * support reference counting.
+ */
+P_LIB_API pboolean p_library_loader_is_ref_counted (void);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PLIBRARYLOADER_H */
diff --git a/3rdparty/plibsys/src/plibsys-private.h b/3rdparty/plibsys/src/plibsys-private.h
new file mode 100644
index 0000000..75a9507
--- /dev/null
+++ b/3rdparty/plibsys/src/plibsys-private.h
@@ -0,0 +1,86 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PLIBSYS_PRIVATE_H
+#define PLIBSYS_HEADER_PLIBSYS_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+
+P_BEGIN_DECLS
+
+#ifndef PLIBSYS_HAS_SOCKLEN_T
+# ifdef P_OS_VMS
+typedef unsigned int socklen_t;
+# else
+typedef int socklen_t;
+# endif
+#endif
+
+#ifndef PLIBSYS_HAS_SOCKADDR_STORAGE
+/* According to RFC 2553 */
+# define _PLIBSYS_SS_MAXSIZE 128
+# define _PLIBSYS_SS_ALIGNSIZE (sizeof (pint64))
+
+# ifdef PLIBSYS_SOCKADDR_HAS_SA_LEN
+# define _PLIBSYS_SS_PAD1SIZE (_PLIBSYS_SS_ALIGNSIZE - (sizeof (puchar) + sizeof (puchar)))
+# else
+# define _PLIBSYS_SS_PAD1SIZE (_PLIBSYS_SS_ALIGNSIZE - sizeof (puchar))
+# endif
+
+# define _PLIBSYS_SS_PAD2SIZE (_PLIBSYS_SS_MAXSIZE - (sizeof (puchar) + _PLIBSYS_SS_PAD1SIZE + _PLIBSYS_SS_ALIGNSIZE))
+
+struct sockaddr_storage {
+# ifdef PLIBSYS_SOCKADDR_HAS_SA_LEN
+ puchar ss_len;
+# endif
+# ifdef PLIBSYS_SIZEOF_SAFAMILY_T
+# if (PLIBSYS_SIZEOF_SAFAMILY_T == 1)
+ puchar ss_family;
+# elif (PLIBSYS_SIZEOF_SAFAMILY_T == 2)
+ pushort ss_family;
+# else
+ puint ss_family;
+# endif
+# else
+# ifdef PLIBSYS_SOCKADDR_HAS_SA_LEN
+ puchar ss_family;
+# else
+ pushort ss_family;
+# endif
+# endif
+ pchar __ss_pad1[_PLIBSYS_SS_PAD1SIZE];
+ pint64 __ss_align;
+ pchar __ss_pad2[_PLIBSYS_SS_PAD2SIZE];
+};
+#endif
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PLIBSYS_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/plibsys.h b/3rdparty/plibsys/src/plibsys.h
new file mode 100644
index 0000000..c322747
--- /dev/null
+++ b/3rdparty/plibsys/src/plibsys.h
@@ -0,0 +1,64 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PLIBSYS_HEADER_PLIBSYS_H
+#define PLIBSYS_HEADER_PLIBSYS_H
+
+#define PLIBSYS_H_INSIDE
+
+#include "plibsysconfig.h"
+#include "patomic.h"
+#include "pcondvariable.h"
+#include "pcryptohash.h"
+#include "pdir.h"
+#include "perror.h"
+#include "pfile.h"
+#include "phashtable.h"
+#include "pinifile.h"
+#include "plibraryloader.h"
+#include "plist.h"
+#include "pmacros.h"
+#include "pmacroscompiler.h"
+#include "pmacroscpu.h"
+#include "pmacrosos.h"
+#include "pmain.h"
+#include "pmem.h"
+#include "pmutex.h"
+#include "pprocess.h"
+#include "prwlock.h"
+#include "psemaphore.h"
+#include "pshm.h"
+#include "pshmbuffer.h"
+#include "psocket.h"
+#include "psocketaddress.h"
+#include "pspinlock.h"
+#include "pstdarg.h"
+#include "pstring.h"
+#include "ptimeprofiler.h"
+#include "ptree.h"
+#include "ptypes.h"
+#include "puthread.h"
+
+#endif /* PLIBSYS_HEADER_PLIBSYS_H */
diff --git a/3rdparty/plibsys/src/plibsysconfig.h.in b/3rdparty/plibsys/src/plibsysconfig.h.in
new file mode 100644
index 0000000..db06020
--- /dev/null
+++ b/3rdparty/plibsys/src/plibsysconfig.h.in
@@ -0,0 +1,76 @@
+#ifndef PLIBSYS_HEADER_PLIBSYSCONFIG_H
+#define PLIBSYS_HEADER_PLIBSYSCONFIG_H
+
+#define PLIBSYS_VERSION_MAJOR @PLIBSYS_VERSION_MAJOR@
+#define PLIBSYS_VERSION_MINOR @PLIBSYS_VERSION_MINOR@
+#define PLIBSYS_VERSION_PATCH @PLIBSYS_VERSION_PATCH@
+#define PLIBSYS_VERSION_STR "@PLIBSYS_VERSION@"
+#define PLIBSYS_VERSION @PLIBSYS_VERSION_NUM@
+
+#cmakedefine PLIBSYS_NEED_WINDOWS_H
+#cmakedefine PLIBSYS_NEED_FLOAT_H
+#cmakedefine PLIBSYS_NEED_LIMITS_H
+#cmakedefine PLIBSYS_NEED_VALUES_H
+#cmakedefine PLIBSYS_NEED_PTHREAD_NP_H
+#cmakedefine PLIBSYS_IS_BIGENDIAN
+#cmakedefine PLIBSYS_SIZEOF_SAFAMILY_T @PLIBSYS_SIZEOF_SAFAMILY_T@
+#cmakedefine PLIBSYS_VA_COPY @PLIBSYS_VA_COPY@
+
+#define PLIBSYS_NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
+#define PLIBSYS_NTDDI_VERSION_FROM_WIN32_WINNT(ver) PLIBSYS_NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
+
+#ifdef PLIBSYS_NEED_WINDOWS_H
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x501
+# endif
+# ifndef NTDDI_VERSION
+# define NTDDI_VERSION PLIBSYS_NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
+# endif
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <windows.h>
+#endif
+
+#include <pmacros.h>
+
+#ifdef PLIBSYS_NEED_FLOAT_H
+# include <float.h>
+#endif
+
+#ifdef PLIBSYS_NEED_LIMITS_H
+# include <limits.h>
+#endif
+
+#ifdef PLIBSYS_NEED_VALUES_H
+# include <values.h>
+#endif
+
+P_BEGIN_DECLS
+
+#define P_MINFLOAT @PLIBSYS_FLOAT_MIN@
+#define P_MAXFLOAT @PLIBSYS_FLOAT_MAX@
+#define P_MINDOUBLE @PLIBSYS_DOUBLE_MIN@
+#define P_MAXDOUBLE @PLIBSYS_DOUBLE_MAX@
+#define P_MINSHORT @PLIBSYS_SHORT_MIN@
+#define P_MAXSHORT @PLIBSYS_SHORT_MAX@
+#define P_MAXUSHORT @PLIBSYS_USHORT_MAX@
+#define P_MININT @PLIBSYS_INT_MIN@
+#define P_MAXINT @PLIBSYS_INT_MAX@
+#define P_MAXUINT @PLIBSYS_UINT_MAX@
+#define P_MINLONG @PLIBSYS_LONG_MIN@
+#define P_MAXLONG @PLIBSYS_LONG_MAX@
+#define P_MAXULONG @PLIBSYS_ULONG_MAX@
+
+@PLIBSYS_SIZEOF_VOID_P_CODE@
+@PLIBSYS_SIZEOF_SIZE_T_CODE@
+@PLIBSYS_SIZEOF_LONG_CODE@
+
+#ifdef PLIBSYS_IS_BIGENDIAN
+# define P_BYTE_ORDER P_BIG_ENDIAN
+#else
+# define P_BYTE_ORDER P_LITTLE_ENDIAN
+#endif
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PLIBSYSCONFIG_H */
diff --git a/3rdparty/plibsys/src/plist.c b/3rdparty/plibsys/src/plist.c
new file mode 100644
index 0000000..ccb5dee
--- /dev/null
+++ b/3rdparty/plibsys/src/plist.c
@@ -0,0 +1,174 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "plist.h"
+
+#include <stdlib.h>
+
+P_LIB_API PList *
+p_list_append (PList *list, ppointer data)
+{
+ PList *item, *cur;
+
+ if (P_UNLIKELY ((item = p_malloc0 (sizeof (PList))) == NULL)) {
+ P_ERROR ("PList::p_list_append: failed to allocate memory");
+ return list;
+ }
+
+ item->data = data;
+
+ /* List is empty */
+ if (P_UNLIKELY (list == NULL))
+ return item;
+
+ for (cur = list; cur->next != NULL; cur = cur->next)
+ ;
+ cur->next = item;
+
+ return list;
+}
+
+P_LIB_API PList *
+p_list_remove (PList *list, ppointer data)
+{
+ PList *cur, *prev, *head;
+
+ if (P_UNLIKELY (list == NULL))
+ return NULL;
+
+ for (head = list, prev = NULL, cur = list; cur != NULL; prev = cur, cur = cur->next) {
+ if (cur->data == data) {
+ if (prev == NULL)
+ head = cur->next;
+ else
+ prev->next = cur->next;
+
+ p_free (cur);
+
+ break;
+ }
+ }
+
+ return head;
+}
+
+P_LIB_API void
+p_list_foreach (PList *list, PFunc func, ppointer user_data)
+{
+ PList *cur;
+
+ if (P_UNLIKELY (list == NULL || func == NULL))
+ return;
+
+ for (cur = list; cur != NULL; cur = cur->next)
+ func (cur->data, user_data);
+}
+
+P_LIB_API void
+p_list_free (PList *list)
+{
+ PList *cur, *next;
+
+ if (P_UNLIKELY (list == NULL))
+ return;
+
+ for (next = cur = list; cur != NULL && next != NULL; cur = next) {
+ next = cur->next;
+ p_free (cur);
+ }
+}
+
+P_LIB_API PList *
+p_list_last (PList *list)
+{
+ PList *cur;
+
+ if (P_UNLIKELY (list == NULL))
+ return NULL;
+
+ for (cur = list; cur->next != NULL; cur = cur->next)
+ ;
+
+ return cur;
+}
+
+P_LIB_API psize
+p_list_length (const PList *list)
+{
+ const PList *cur;
+ psize ret;
+
+ if (P_UNLIKELY (list == NULL))
+ return 0;
+
+ for (cur = list, ret = 1; cur->next != NULL; cur = cur->next, ++ret)
+ ;
+
+ return ret;
+}
+
+P_LIB_API PList *
+p_list_prepend (PList *list, ppointer data)
+{
+ PList *item;
+
+ if (P_UNLIKELY ((item = p_malloc0 (sizeof (PList))) == NULL)) {
+ P_ERROR ("PList::p_list_prepend: failed to allocate memory");
+ return list;
+ }
+
+ item->data = data;
+
+ /* List is empty */
+ if (P_UNLIKELY (list == NULL))
+ return item;
+
+ item->next = list;
+
+ return item;
+}
+
+P_LIB_API PList *
+p_list_reverse (PList *list)
+{
+ PList *prev, *cur, *tmp;
+
+ if (P_UNLIKELY (list == NULL))
+ return NULL;
+
+ prev = list;
+ cur = list->next;
+ prev->next = NULL;
+
+ while (cur != NULL) {
+ tmp = cur->next;
+ cur->next = prev;
+ prev = cur;
+ cur = tmp;
+ }
+
+ return prev;
+}
diff --git a/3rdparty/plibsys/src/plist.h b/3rdparty/plibsys/src/plist.h
new file mode 100644
index 0000000..e72ba0c
--- /dev/null
+++ b/3rdparty/plibsys/src/plist.h
@@ -0,0 +1,199 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file plist.h
+ * @brief Singly linked list
+ * @author Alexander Saprykin
+ *
+ * A singly linked list is a data structure consists of the nodes which
+ * represent a sequence. Each node contains a data pointer and a pointer to the
+ * next node. Every node has a link only to the next node, hence list is a
+ * singly linked (in a single direction).
+ *
+ * As the singly linked list is a linear collection of the nodes with the
+ * sequential access, it has an O(N) average complexity for appending, removing
+ * and searching operations. Prepending a node takes O(1) constant time. Thus it
+ * is not intended for heavy usage, please refer to #PHashTable or #PTree if you
+ * are working with large data sets.
+ *
+ * Before the first usage you must initialize a #PList variable to NULL. After
+ * that you can use the p_list_append(), p_list_prepend(), p_list_remove() and
+ * p_list_reverse() routines to update that variable:
+ * @code
+ * PList *list;
+ * ppointer data;
+ *
+ * list = NULL;
+ * data = my_obj_new ();
+ *
+ * list = p_list_append (list, data);
+ * @endcode
+ * #PList stores only the pointers to the data, so you must free used memory
+ * manually, p_list_free() only frees list's internal memory, not the data it
+ * stores the pointers for. The best approach to free used memory is the
+ * p_list_foreach() routine:
+ * @code
+ * PList *list;
+ * ...
+ * p_list_foreach (list, (PFunc) my_free_func, my_data);
+ * p_list_free (list);
+ * @endcode
+ * Also you can use #P_INT_TO_POINTER and #P_POINTER_TO_INT macros to store
+ * integers (up to 32-bit) without allocating memory for them:
+ * @code
+ * PList *list;
+ * pint a;
+ *
+ * list = p_list_append (list, P_INT_TO_POINTER (12));
+ * a = P_POINTER_TO_INT (list->data);
+ * @endcode
+ * #PList can store several nodes with the same pointer value, but
+ * p_list_remove() will remove only the first matching node.
+ *
+ * If you need to add large amount of nodes at once it is better to prepend them
+ * and then reverse the list.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PLIST_H
+#define PLIBSYS_HEADER_PLIST_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Typedef for a list node. */
+typedef struct PList_ PList;
+
+/** Node for a singly linked list. */
+struct PList_ {
+ ppointer data; /**< Pointer to the node data. */
+ PList *next; /**< Next list node. */
+};
+
+/**
+ * @brief Appends data to a list.
+ * @param list #PList for appending the data.
+ * @param data Data to append.
+ * @return Pointer to the updated list in case of success, @a list otherwise.
+ * @since 0.0.1
+ *
+ * Before appending the first node to the list, @a list argument must be
+ * initialized with NULL. Otherwise behavior is unpredictable.
+ */
+P_LIB_API PList * p_list_append (PList *list,
+ ppointer data) P_GNUC_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Removes data from a list.
+ * @param list List to remove the data from.
+ * @param data Data to remove.
+ * @return Pointer to the updated list in case of success, @a list otherwise.
+ * @since 0.0.1
+ *
+ * It searches for the first matching occurrence in the @a list and removes
+ * that node. Note that it removes only the pointer from the @a list, not the
+ * data it pointers to, so you need to free the data manually.
+ */
+P_LIB_API PList * p_list_remove (PList *list,
+ ppointer data) P_GNUC_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Calls a specified function for each list node.
+ * @param list List to go through.
+ * @param func Pointer for the callback function.
+ * @param user_data User defined data, may be NULL.
+ * @since 0.0.1
+ *
+ * This function goes through the whole @a list and calls @a func for each node.
+ * The @a func will receive pointer to the node's data and @a user_data. You can
+ * use it to free the data:
+ * @code
+ * p_list_foreach (list, (PFunc) free, NULL);
+ * p_list_free (list);
+ * @endcode
+ */
+P_LIB_API void p_list_foreach (PList *list,
+ PFunc func,
+ ppointer user_data);
+
+/**
+ * @brief Frees list memory.
+ * @param list List to free.
+ * @since 0.0.1
+ *
+ * This function frees only the list's internal memory, not the data in the
+ * pointers stored in the nodes. Don't forget to free all the data stored in the
+ * list manually.
+ */
+P_LIB_API void p_list_free (PList *list);
+
+/**
+ * @brief Gets the last node from the list.
+ * @param list List to get the node from.
+ * @return Pointer to the last @a list node, NULL if the @a list is empty.
+ * @since 0.0.1
+ */
+P_LIB_API PList * p_list_last (PList *list);
+
+/**
+ * @brief Gets the number of list nodes.
+ * @param list List to count nodes in.
+ * @return Number of nodes in the @a list.
+ * @since 0.0.1
+ * @note This function will iterate through the whole @a list, so don't use it
+ * in condition of the for-loop or in the code which is repeated a lot of times.
+ */
+P_LIB_API psize p_list_length (const PList *list);
+
+/**
+ * @brief Prepends data to a list.
+ * @param list #PList for prepending the data.
+ * @param data Data to prepend.
+ * @return Pointer to the updated list in case of success, @a list otherwise.
+ * @since 0.0.1
+ *
+ * Before prepending the first node to the list, @a list argument must be
+ * initialized with NULL. Otherwise behavior is unpredictable.
+ */
+P_LIB_API PList * p_list_prepend (PList *list,
+ ppointer data) P_GNUC_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Reverses the list order.
+ * @param list #PList to reverse the order.
+ * @return Pointer to the top of the reversed list.
+ * @since 0.0.1
+ */
+P_LIB_API PList * p_list_reverse (PList *list) P_GNUC_WARN_UNUSED_RESULT;
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PLIST_H */
diff --git a/3rdparty/plibsys/src/pmacros.h b/3rdparty/plibsys/src/pmacros.h
new file mode 100644
index 0000000..7751337
--- /dev/null
+++ b/3rdparty/plibsys/src/pmacros.h
@@ -0,0 +1,302 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmacros.h
+ * @brief Miscellaneous macros
+ * @author Alexander Saprykin
+ *
+ * All the macros are completely independent of any other platform-specific
+ * headers, thus gurantee to work with any compiler under any operating system
+ * in the same way as they are used within the library.
+ *
+ * This family of macros provides various additional capabilities (compiler
+ * hints, attributes, version, etc.).
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMACROS_H
+#define PLIBSYS_HEADER_PMACROS_H
+
+#include <pmacroscompiler.h>
+#include <pmacroscpu.h>
+#include <pmacrosos.h>
+
+#include <stdio.h>
+
+/* For Clang */
+#ifndef __has_attribute
+# define __has_attribute(x) 0
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/**
+ * @def P_GNUC_WARN_UNUSED_RESULT
+ * @brief Gives a warning if the result returned from a function is not being
+ * used.
+ * @since 0.0.1
+ */
+
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \
+ __has_attribute(warn_unused_result)
+# define P_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define P_GNUC_WARN_UNUSED_RESULT
+#endif
+
+/**
+ * @def P_LIB_INTERNAL_API
+ * @brief Marks a symbol (variable, function) as local.
+ * @since 0.0.4
+ *
+ * Local symbols are not exported during the linkage and are not available from
+ * the outside of the module they are defined in. Use it for internal API.
+ *
+ * @note Some compilers allow to put this attribute at the beginning of the
+ * symbol declaration, and some also at the end of the declaration. Thus it is
+ * better to put it in the beginning for more portability.
+ */
+
+/**
+ * @def P_LIB_GLOBAL_API
+ * @brief Marks a symbol (variable, function) as global.
+ * @since 0.0.4
+ *
+ * Global symbols are exported during the linkage and are available from the
+ * outside of the module they are defined in. Use it for public API.
+ *
+ * @note Some compilers allow to put this attribute at the beginning of the
+ * symbol declaration, and some also at the end of the declaration. Thus it is
+ * better to put it in the beginning for more portability.
+ */
+
+/*
+ * Oracle Solaris Studio since version 12 has visibility attribute for C
+ * compiler, and since version 12.2 for C++ compiler, or since version 8.0
+ * specific __global attribute which is the same.
+ * IBM XL C has support for visibility attributes since version 13.1.
+ * HP C/aC++ has support for visibility attributes since version A.06.15.
+ */
+
+#if defined(P_CC_MSVC) || defined(P_CC_BORLAND) || defined(P_CC_WATCOM) || \
+ defined(P_OS_OS2) || (defined(P_OS_BEOS) && !defined(P_CC_GNU)) || \
+ (defined(P_OS_WIN) && defined(P_CC_PGI)) || \
+ ((defined(P_OS_WIN) || defined(P_OS_CYGWIN) || defined(P_OS_MSYS)) && defined(P_CC_GNU))
+# define P_LIB_GLOBAL_API __declspec(dllexport)
+# define P_LIB_INTERNAL_API
+#elif ((__GNUC__ >= 4) && !defined(P_OS_SOLARIS) && !defined(P_OS_HPUX) && !defined(P_OS_AIX)) || \
+ (defined(P_CC_SUN) && __SUNPRO_C >= 0x590) || \
+ (defined(P_CC_SUN) && __SUNPRO_CC >= 0x5110) || \
+ (defined(P_CC_XLC) && __xlC__ >= 0x0D01) || \
+ (defined(P_CC_HP) && __HP_aCC >= 0x061500) || \
+ (defined(P_CC_HP) && __HP_cc >= 0x061500) || \
+ __has_attribute(visibility)
+# define P_LIB_GLOBAL_API __attribute__ ((visibility ("default")))
+# define P_LIB_INTERNAL_API __attribute__ ((visibility ("hidden")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define P_LIB_GLOBAL_API __global
+# define P_LIB_INTERNAL_API __hidden
+#else
+# define P_LIB_GLOBAL_API
+# define P_LIB_INTERNAL_API
+#endif
+
+/**
+ * @def P_LIB_API
+ * @brief Exports a symbol from a shared library.
+ * @since 0.0.1
+ */
+
+#define P_LIB_API P_LIB_GLOBAL_API
+
+/* Oracle Solaris Studio at least since 12.2 has ((noreturn)) attribute */
+
+/**
+ * @def P_NO_RETURN
+ * @brief Notifies a compiler that a function will never return a value (i.e.
+ * due to the abort () call).
+ * @since 0.0.1
+ */
+
+#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+# define P_NO_RETURN _Noreturn
+#elif defined(P_CC_MSVC) || (defined(P_CC_BORLAND) && __BORLANDC__ >= 0x0550)
+# define P_NO_RETURN __declspec(noreturn)
+#elif __has_attribute(noreturn) || \
+ defined(P_CC_GNU) || \
+ (defined(P_CC_SUN) && __SUNPRO_C >= 0x5110) || \
+ (defined(P_CC_SUN) && __SUNPRO_CC >= 0x5110)
+# define P_NO_RETURN __attribute__((noreturn))
+#else
+# define P_NO_RETURN
+#endif
+
+/**
+ * @def P_LIKELY
+ * @brief Hints a compiler that a condition is likely to be true so it can
+ * perform code optimizations.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_UNLIKELY
+ * @brief Hints a compiler that a condition is likely to be false so it can
+ * perform code optimizations.
+ * @since 0.0.1
+ */
+
+#if (defined(P_CC_GNU) && (__GNUC__ > 2 && __GNUC_MINOR__ > 0)) || \
+ (defined(P_CC_INTEL) && __INTEL_COMPILER >= 800) || \
+ (defined(P_CC_XLC) && __xlC__ >= 0x0900) || \
+ __has_builtin(__builtin_expect)
+# define P_LIKELY(x) __builtin_expect(!!(x), 1)
+# define P_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+# define P_LIKELY(x) (x)
+# define P_UNLIKELY(x) (x)
+#endif
+
+/**
+ * @def P_UNUSED
+ * @brief Macro to by-pass a compiler warning on unused variables.
+ * @since 0.0.1
+ */
+#define P_UNUSED(a) ((void) a)
+
+/**
+ * @def P_WARNING
+ * @brief Prints a warning message.
+ * @param msg Message to print.
+ * @since 0.0.1
+ */
+#define P_WARNING(msg) printf ("** Warning: %s **\n", msg)
+
+/**
+ * @def P_ERROR
+ * @brief Prints an error message.
+ * @param msg Message to print.
+ * @since 0.0.1
+ */
+#define P_ERROR(msg) printf ("** Error: %s **\n", msg)
+
+/**
+ * @def P_DEBUG
+ * @brief Prints a debug message.
+ * @param msg Message to print.
+ * @since 0.0.1
+ */
+#define P_DEBUG(msg) printf ("** Debug: %s **\n", msg)
+
+#ifdef DOXYGEN
+# define PLIBSYS_VERSION_MAJOR
+# define PLIBSYS_VERSION_MINOR
+# define PLIBSYS_VERSION_PATCH
+# define PLIBSYS_VERSION_STR
+# define PLIBSYS_VERSION
+#endif
+
+/**
+ * @def PLIBSYS_VERSION_MAJOR
+ * @brief Library major version number.
+ * @since 0.0.1
+ * @note This is the version against which the application is compiled.
+ */
+
+/**
+ * @def PLIBSYS_VERSION_MINOR
+ * @brief Library minor version number.
+ * @since 0.0.1
+ * @note This is the version against which the application is compiled.
+ */
+
+/**
+ * @def PLIBSYS_VERSION_PATCH
+ * @brief Library patch version number.
+ * @since 0.0.1
+ * @note This is the version against which the application is compiled.
+ */
+
+/**
+ * @def PLIBSYS_VERSION_STR
+ * @brief Library full version in the string form, i.e. "0.0.1".
+ * @since 0.0.1
+ * @note This is the version against which the application is compiled.
+ * @sa p_libsys_version()
+ */
+
+/**
+ * @def PLIBSYS_VERSION
+ * @brief Library full version in the form 0xMMNNPP (MM = major, NN = minor,
+ * PP = patch), i.e. 0x000001.
+ * @since 0.0.1
+ * @note This is the version against which the application is compiled.
+ * @sa p_libsys_version()
+ */
+
+/**
+ * @def PLIBSYS_VERSION_CHECK
+ * @brief Makes a library version number which can be used to check the library
+ * version against which the application is compiled.
+ * @param major Major version number to check.
+ * @param minor Minor version number to check.
+ * @param patch Minor version number to check.
+ * @since 0.0.1
+ * @sa p_libsys_version()
+ *
+ * @code
+ * if (PLIBSYS_VERSION >= PLIBSYS_VERSION_CHECK (0, 0, 1))
+ * ...
+ * @endcode
+ */
+#define PLIBSYS_VERSION_CHECK(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
+
+/**
+ * @def P_BEGIN_DECLS
+ * @brief Starts .h file declarations to be exported as C functions.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_END_DECLS
+ * @brief Closes .h file declarations to be exported as C functions, should be
+ * always used after #P_BEGIN_DECLS.
+ * @since 0.0.1
+ */
+
+#ifdef __cplusplus
+# define P_BEGIN_DECLS extern "C" {
+# define P_END_DECLS }
+#else
+# define P_BEGIN_DECLS
+# define P_END_DECLS
+#endif
+
+#endif /* PLIBSYS_HEADER_PMACROS_H */
diff --git a/3rdparty/plibsys/src/pmacroscompiler.h b/3rdparty/plibsys/src/pmacroscompiler.h
new file mode 100644
index 0000000..cbe4cc0
--- /dev/null
+++ b/3rdparty/plibsys/src/pmacroscompiler.h
@@ -0,0 +1,253 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmacroscompiler.h
+ * @brief Compiler detection macros
+ * @author Alexander Saprykin
+ *
+ * All the macros are completely independent of any other platform-specific
+ * headers, thus gurantee to work with any compiler under any operating system
+ * in the same way as they are used within the library.
+ *
+ * This family of macros provides compiler detection and defines one or several
+ * of P_CC_x macros.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMACROSCOMPILER_H
+#define PLIBSYS_HEADER_PMACROSCOMPILER_H
+
+/*
+ * List of supported compilers (P_CC_x):
+ *
+ * MSVC - Microsoft Visual C/C++
+ * GNU - GNU C/C++
+ * MINGW - MinGW C/C++
+ * INTEL - Intel C/C++
+ * CLANG - LLVM Clang C/C++
+ * SUN - Sun WorkShop/Studio C/C++
+ * XLC - IBM XL C/C++
+ * HP - HP C/aC++
+ * DEC - DEC C/C++
+ * MIPS - MIPSpro C/C++
+ * USLC - SCO OUDK and UDK C/C++
+ * WATCOM - Watcom C/C++
+ * BORLAND - Borland C/C++
+ * PGI - Portland Group C/C++
+ * CRAY - CRAY C/C++
+ */
+
+/**
+ * @def P_CC_MSVC
+ * @brief Microsoft Visual C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_GNU
+ * @brief GNU C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_MINGW
+ * @brief MinGW C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_INTEL
+ * @brief Intel C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_CLANG
+ * @brief LLVM Clang C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_SUN
+ * @brief Sun WorkShop/Studio C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_XLC
+ * @brief IBM XL C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_HP
+ * @brief HP C/aC++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_DEC
+ * @brief DEC C/C++ compiler.
+ * @since 0.0.2
+ */
+
+/**
+ * @def P_CC_MIPS
+ * @brief MIPSpro C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_USLC
+ * @brief SCO OUDK and UDK C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_WATCOM
+ * @brief Watcom C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_BORLAND
+ * @brief Borland C/C++ compiler.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_CC_PGI
+ * @brief Portland Group C/C++ compiler.
+ * @since 0.0.3
+ */
+
+/**
+ * @def P_CC_CRAY
+ * @brief Cray C/C++ compiler.
+ * @since 0.0.4
+ */
+
+#if defined(_MSC_VER)
+# define P_CC_MSVC
+# if defined(__INTEL_COMPILER)
+# define P_CC_INTEL
+# endif
+# if defined(__clang__)
+# define P_CC_CLANG
+# endif
+#elif defined(__GNUC__)
+# define P_CC_GNU
+# if defined(__MINGW32__)
+# define P_CC_MINGW
+# endif
+# if defined(__INTEL_COMPILER)
+# define P_CC_INTEL
+# endif
+# if defined(__clang__)
+# define P_CC_CLANG
+# endif
+# if defined(_CRAYC)
+# define P_CC_CRAY
+# endif
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# define P_CC_SUN
+#elif defined(__xlc__) || defined(__xlC__)
+# define P_CC_XLC
+#elif defined(__HP_cc) || defined(__HP_aCC)
+# define P_CC_HP
+#elif defined (__DECC) || defined(__DECCXX)
+# define P_CC_DEC
+#elif (defined(__sgi) || defined(sgi)) && \
+ (defined(_COMPILER_VERSION) || defined(_SGI_COMPILER_VERSION))
+# define P_CC_MIPS
+#elif defined(__USLC__) && defined(__SCO_VERSION__)
+# define P_CC_USLC
+#elif defined(__WATCOMC__)
+# define P_CC_WATCOM
+#elif defined(__BORLANDC__)
+# define P_CC_BORLAND
+#elif defined(__INTEL_COMPILER)
+# define P_CC_INTEL
+#elif defined(__PGI)
+# define P_CC_PGI
+#elif defined(_CRAYC)
+# define P_CC_CRAY
+#endif
+
+/* We need this to generate full Doxygen documentation */
+
+#ifdef DOXYGEN
+# ifndef P_CC_MSVC
+# define P_CC_MSVC
+# endif
+# ifndef P_CC_GNU
+# define P_CC_GNU
+# endif
+# ifndef P_CC_MINGW
+# define P_CC_MINGW
+# endif
+# ifndef P_CC_INTEL
+# define P_CC_INTEL
+# endif
+# ifndef P_CC_CLANG
+# define P_CC_CLANG
+# endif
+# ifndef P_CC_SUN
+# define P_CC_SUN
+# endif
+# ifndef P_CC_XLC
+# define P_CC_XLC
+# endif
+# ifndef P_CC_HP
+# define P_CC_HP
+# endif
+# ifndef P_CC_DEC
+# define P_CC_DEC
+# endif
+# ifndef P_CC_MIPS
+# define P_CC_MIPS
+# endif
+# ifndef P_CC_USLC
+# define P_CC_USLC
+# endif
+# ifndef P_CC_WATCOM
+# define P_CC_WATCOM
+# endif
+# ifndef P_CC_BORLAND
+# define P_CC_BORLAND
+# endif
+# ifndef P_CC_PGI
+# define P_CC_PGI
+# endif
+# ifndef P_CC_CRAY
+# define P_CC_CRAY
+# endif
+#endif
+
+#endif /* PLIBSYS_HEADER_PMACROSCOMPILER_H */
diff --git a/3rdparty/plibsys/src/pmacroscpu.h b/3rdparty/plibsys/src/pmacroscpu.h
new file mode 100644
index 0000000..d1b0cbb
--- /dev/null
+++ b/3rdparty/plibsys/src/pmacroscpu.h
@@ -0,0 +1,627 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmacroscpu.h
+ * @brief CPU detection macros
+ * @author Alexander Saprykin
+ *
+ * All the macros are completely independent of any other platform-specific
+ * headers, thus gurantee to work with any compiler under any operating system
+ * in the same way as they are used within the library.
+ *
+ * This family of macros provides CPU detection and defines one or several of
+ * P_CPU_x macros.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMACROSCPU_H
+#define PLIBSYS_HEADER_PMACROSCPU_H
+
+/*
+ * List of supported CPU architectures (P_CPU_x):
+ *
+ * ALPHA - Alpha
+ * ARM - ARM architecture revision:
+ * v2, v3, v4, v5, v6, v7, v8
+ * ARM_32 - ARM 32-bit
+ * ARM_64 - ARM 64-bit
+ * ARM_V2 - ARMv2 instruction set
+ * ARM_V3 - ARMv3 instruction set
+ * ARM_V4 - ARMv4 instruction set
+ * ARM_V5 - ARMv5 instruction set
+ * ARM_V6 - ARMv6 instruction set
+ * ARM_V7 - ARMv7 instruction set
+ * ARM_V8 - ARMv8 instruction set
+ * X86 - x86 architecture revision:
+ * 3, 4, 5, 6 (Intel P6 or better)
+ * X86_32 - x86 32-bit
+ * X86_64 - x86 64-bit
+ * IA64 - Intel Itanium (IA-64)
+ * MIPS - MIPS
+ * MIPS_I - MIPS I
+ * MIPS_II - MIPS II
+ * MIPS_III - MIPS III
+ * MIPS_IV - MIPS IV
+ * MIPS_32 - MIPS32
+ * MIPS_64 - MIPS64
+ * POWER - PowerPC
+ * POWER_32 - PowerPC 32-bit
+ * POWER_64 - PowerPC 64-bit
+ * SPARC - Sparc
+ * SPARC_V8 - Sparc V8
+ * SPARC_V9 - Sparc V9
+ * HPPA - HPPA-RISC
+ * HPPA_32 - HPPA-RISC 32-bit
+ * HPPA_64 - HPPA-RISC 64-bit
+ */
+
+/**
+ * @def P_CPU_ALPHA
+ * @brief DEC Alpha architecture.
+ * @since 0.0.3
+ */
+
+/**
+ * @def P_CPU_ARM
+ * @brief ARM architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any ARM target. It contains an architecture
+ * revision number. One of the revision specific macros (P_CPU_ARM_Vx) is also
+ * defined, as well as #P_CPU_ARM_32 or #P_CPU_ARM_64.
+ */
+
+/**
+ * @def P_CPU_ARM_32
+ * @brief ARM 32-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARM 32-bit target. One of the revision specific
+ * macros (P_CPU_ARM_Vx) is also defined, as well as #P_CPU_ARM.
+ */
+
+/**
+ * @def P_CPU_ARM_64
+ * @brief ARM 64-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARM 64-bit target. One of the revision specific
+ * macros (P_CPU_ARM_Vx) is also defined, as well as #P_CPU_ARM.
+ */
+
+/**
+ * @def P_CPU_ARM_V2
+ * @brief ARMv2 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv2 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V3
+ * @brief ARMv3 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv3 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V4
+ * @brief ARMv4 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv4 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V5
+ * @brief ARMv5 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv5 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V6
+ * @brief ARMv6 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv6 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V7
+ * @brief ARMv7 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv7 target. #P_CPU_ARM_32 and #P_CPU_ARM macros
+ * are also defined.
+ */
+
+/**
+ * @def P_CPU_ARM_V8
+ * @brief ARMv8 architecture revision.
+ * @since 0.0.3
+ *
+ * This macro is defined for ARMv8 target. #P_CPU_ARM_32 or #P_CPU_ARM_64 macro
+ * is defined, as well as #P_CPU_ARM.
+ */
+
+/**
+ * @def P_CPU_X86
+ * @brief Intel x86 architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any x86 target. It contains an architecture
+ * revision number (3 for i386 and lower, 4 for i486, 5 for i586, 6 for i686 and
+ * better). One of the architecture specific macros (P_CPU_X86_xx) is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_X86_32
+ * @brief Intel x86 32-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for x86 32-bit target. #P_CPU_X86 macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_X86_64
+ * @brief Intel x86 64-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for x86 64-bit target. #P_CPU_X86 macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_IA64
+ * @brief Intel Itanium (IA-64) architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for Intel Itanium (IA-64) target.
+ */
+
+/**
+ * @def P_CPU_MIPS
+ * @brief MIPS architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any MIPS target. Some other specific macros
+ * (P_CPU_MIPS_xx) for different MIPS ISAs may be defined.
+ */
+
+/**
+ * @def P_CPU_MIPS_I
+ * @brief MIPS I ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS I target. #P_CPU_MIPS is also defined, as well
+ * as probably some other ISA macros (P_CPU_MIPS_xx).
+ */
+
+/**
+ * @def P_CPU_MIPS_II
+ * @brief MIPS II ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS II target. #P_CPU_MIPS and #P_CPU_MIPS_I are
+ * also defined, as well as probably some other ISA macros (P_CPU_MIPS_xx).
+ */
+
+/**
+ * @def P_CPU_MIPS_III
+ * @brief MIPS III ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS III target. #P_CPU_MIPS, #P_CPU_MIPS_I and
+ * #P_CPU_MIPS_II are also defined, as well as probably some other ISA macros
+ * (P_CPU_MIPS_xx).
+ */
+
+/**
+ * @def P_CPU_MIPS_IV
+ * @brief MIPS IV ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS IV target. #P_CPU_MIPS, #P_CPU_MIPS_I,
+ * #P_CPU_MIPS_II and #P_CPU_MIPS_III are also defined, as well as probably some
+ * other ISA macros (P_CPU_MIPS_xx).
+ */
+
+/**
+ * @def P_CPU_MIPS_32
+ * @brief MIPS32 ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS32 target. #P_CPU_MIPS, #P_CPU_MIPS_I and
+ * #P_CPU_MIPS_II.
+ */
+
+/**
+ * @def P_CPU_MIPS_64
+ * @brief MIPS64 ISA.
+ * @since 0.0.3
+ *
+ * This macro is defined for MIPS64 target. #P_CPU_MIPS, #P_CPU_MIPS_I,
+ * #P_CPU_MIPS_II, #P_CPU_MIPS_III, #P_CPU_MIPS_IV and are also defined.
+ */
+
+/**
+ * @def P_CPU_POWER
+ * @brief PowerPC architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any PowerPC target. One of the architecture
+ * specific macros (P_CPU_POWER_xx) is also defined.
+ */
+
+/**
+ * @def P_CPU_POWER_32
+ * @brief PowerPC 32-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for PowerPC 32-bit target. #P_CPU_POWER macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_POWER_64
+ * @brief PowerPC 64-bit architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for PowerPC 64-bit target. #P_CPU_POWER macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_SPARC
+ * @brief Sun SPARC architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any SPARC target. One of the architecture
+ * specific macros (P_CPU_SPARC_xx) is also may be defined.
+ */
+
+/**
+ * @def P_CPU_SPARC_V8
+ * @brief Sun SPARC V8 architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for SPARC V8 target. #P_CPU_SPARC macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_SPARC_V9
+ * @brief Sun SPARC V9 architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for SPARC V9 target. #P_CPU_SPARC macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_HPPA
+ * @brief HP PA-RISC architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for any PA-RISC target. One of the architecture
+ * specific macros (P_CPU_HPPA_xx) is also defined.
+ */
+
+/**
+ * @def P_CPU_HPPA_32
+ * @brief HP PA-RISC 32-bit (1.0, 1.1) architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for PA-RISC 32-bit target. #P_CPU_HPPA macro is also
+ * defined.
+ */
+
+/**
+ * @def P_CPU_HPPA_64
+ * @brief HP PA-RISC 64-bit (2.0) architecture.
+ * @since 0.0.3
+ *
+ * This macro is defined for PA-RISC 64-bit target. #P_CPU_HPPA macro is also
+ * defined.
+ */
+
+#if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
+# define P_CPU_ALPHA
+#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_ARM) || \
+ defined(_M_ARM) || defined(_M_ARM_64) || defined(__arm) || defined(__aarch64__) || \
+ defined(__ARM64__)
+# if defined(__aarch64__) || defined(_M_ARM64) || defined(__ARM64__)
+# define P_CPU_ARM_64
+# else
+# define P_CPU_ARM_32
+# endif
+# if defined(__ARM_ARCH) && __ARM_ARCH > 1
+# define P_CPU_ARM __ARM_ARCH
+# elif defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM > 1
+# define P_CPU_ARM __TARGET_ARCH_ARM
+# elif defined(_M_ARM) && _M_ARM > 1
+# define P_CPU_ARM _M_ARM
+# elif defined(__ARM64_ARCH_8__) || \
+ defined(__ARM_ARCH_8__) || \
+ defined(__ARM_ARCH_8A__) || \
+ defined(__aarch64__) || \
+ defined(__ARMv8__) || \
+ defined(__ARMv8_A__) || \
+ defined(_M_ARM_64) || \\
+ defined(__CORE_CORTEXAV8__)
+# define P_CPU_ARM 8
+# elif defined(__ARM_ARCH_7__) || \
+ defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7R__) || \
+ defined(__ARM_ARCH_7M__) || \
+ defined(__ARM_ARCH_7S__) || \
+ defined(_ARM_ARCH_7) || \
+ defined(__CORE_CORTEXA__)
+# define P_CPU_ARM 7
+# elif defined(__ARM_ARCH_6__) || \
+ defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6T2__) || \
+ defined(__ARM_ARCH_6Z__) || \
+ defined(__ARM_ARCH_6K__) || \
+ defined(__ARM_ARCH_6ZK__) || \
+ defined(__ARM_ARCH_6M__)
+# define P_CPU_ARM 6
+# elif defined(__ARM_ARCH_5__) || \
+ defined(__ARM_ARCH_5E__) || \
+ defined(__ARM_ARCH_5T__) || \
+ defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_5TEJ__)
+# define P_CPU_ARM 5
+# elif defined(__ARM_ARCH_4__) || \
+ defined(__ARM_ARCH_4T__)
+# define P_CPU_ARM 4
+# elif defined(__ARM_ARCH_3__) || \
+ defined(__ARM_ARCH_3M__)
+# define P_CPU_ARM 3
+# elif defined(__ARM_ARCH_2__)
+# define P_CPU_ARM 2
+# else
+# define P_CPU_ARM 0
+# endif
+# if P_CPU_ARM == 8
+# define P_CPU_ARM_V8
+# elif P_CPU_ARM == 7
+# define P_CPU_ARM_V7
+# elif P_CPU_ARM == 6
+# define P_CPU_ARM_V6
+# elif P_CPU_ARM == 5
+# define P_CPU_ARM_V5
+# elif P_CPU_ARM == 4
+# define P_CPU_ARM_V4
+# elif P_CPU_ARM == 3
+# define P_CPU_ARM_V3
+# elif P_CPU_ARM == 2
+# define P_CPU_ARM_V2
+# else
+# error "ARM architecture is uknown or too old"
+# endif
+#elif defined(__i386__) || defined(__i386) || defined(_M_IX86)
+# define P_CPU_X86_32
+# if defined(_M_IX86)
+# if (_M_IX86 >= 300 &&_M_IX86 <= 600)
+# define P_CPU_X86 (_M_IX86 / 100)
+# else
+# define P_CPU_X86 6
+# endif
+# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__)
+# define P_CPU_X86 6
+# elif defined(__i586__) || defined(__k6__) || defined(__pentium__)
+# define P_CPU_X86 5
+# elif defined(__i486__) || defined(__80486__)
+# define P_CPU_X86 4
+# else
+# define P_CPU_X86 3
+# endif
+#elif defined(__x86_64__) || defined(__x86_64) || \
+ defined(__amd64__) || defined(__amd64) || \
+ defined(_M_X64) || defined(_M_AMD64)
+# define P_CPU_X86_64
+# define P_CPU_X86 6
+#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
+# define P_CPU_IA64
+#elif defined(__mips__) || defined(__mips) || defined(_M_MRX000)
+# define P_CPU_MIPS
+# if defined(_M_MRX000)
+# if (_M_MRX000 >= 10000)
+# define P_CPU_MIPS_IV
+# else
+# define P_CPU_MIPS_III
+# endif
+# endif
+# if defined(_MIPS_ARCH_MIPS64) || (defined(__mips) && __mips - 0 >= 64) || \
+ (defined(_MIPS_ISA) && defined(_MIPS_ISA_MIPS64) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS64)
+# define P_CPU_MIPS_64
+# elif defined(_MIPS_ARCH_MIPS32) || (defined(__mips) && __mips - 0 >= 32) || \
+ (defined(_MIPS_ISA) && defined(_MIPS_ISA_MIPS32) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS32)
+# define P_CPU_MIPS_32
+# elif defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4) || \
+ (defined(_MIPS_ISA) && defined(_MIPS_ISA_MIPS4) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS4)
+# define P_CPU_MIPS_IV
+# elif defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3) || \
+ (defined(_MIPS_ISA)&& defined(_MIPS_ISA_MIPS3) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS3)
+# define P_CPU_MIPS_III
+# elif defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2) || \
+ (defined(_MIPS_ISA) && defined(_MIPS_ISA_MIPS2) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS2)
+# define P_CPU_MIPS_II
+# elif defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1) || \
+ (defined(_MIPS_ISA) && defined(_MIPS_ISA_MIPS1) && __MIPS_ISA - 0 >= _MIPS_ISA_MIPS1)
+# define P_CPU_MIPS_I
+# endif
+# if defined(P_CPU_MIPS_64)
+# define P_CPU_MIPS_IV
+# endif
+# if defined(P_CPU_MIPS_IV)
+# define P_CPU_MIPS_III
+# endif
+# if defined(P_CPU_MIPS_32) || defined(P_CPU_MIPS_III)
+# define P_CPU_MIPS_II
+# endif
+# if defined(P_CPU_MIPS_II)
+# define P_CPU_MIPS_I
+# endif
+#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__ppc) || \
+ defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_COM) || \
+ defined(_M_PPC) || defined(_M_MPPC)
+# define P_CPU_POWER
+# if defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__ppc64) || \
+ defined(__64BIT__) || defined(__LP64__) || defined(_LP64)
+# define P_CPU_POWER_64
+# else
+# define P_CPU_POWER_32
+# endif
+#elif defined(__sparc__) || defined(__sparc)
+# define P_CPU_SPARC
+# if defined(__sparc_v9__) || defined(__sparcv9)
+# define P_CPU_SPARC_V9
+# elif defined(__sparc_v8__) || defined(__sparcv8)
+# define P_CPU_SPARC_V8
+# endif
+#elif defined(__hppa__) || defined(__hppa)
+# define P_CPU_HPPA
+# if defined(_PA_RISC2_0) || defined(__RISC2_0__) || defined(__HPPA20__) || defined(__PA8000__)
+# define P_CPU_HPPA_64
+# else
+# define P_CPU_HPPA_32
+# endif
+#endif
+
+/* We need this to generate full Doxygen documentation */
+
+#ifdef DOXYGEN
+# ifndef P_CPU_ALPHA
+# define P_CPU_ALPHA
+# endif
+# ifndef P_CPU_ARM
+# define P_CPU_ARM
+# endif
+# ifndef P_CPU_ARM_32
+# define P_CPU_ARM_32
+# endif
+# ifndef P_CPU_ARM_64
+# define P_CPU_ARM_64
+# endif
+# ifndef P_CPU_ARM_V2
+# define P_CPU_ARM_V2
+# endif
+# ifndef P_CPU_ARM_V3
+# define P_CPU_ARM_V3
+# endif
+# ifndef P_CPU_ARM_V4
+# define P_CPU_ARM_V4
+# endif
+# ifndef P_CPU_ARM_V5
+# define P_CPU_ARM_V5
+# endif
+# ifndef P_CPU_ARM_V6
+# define P_CPU_ARM_V6
+# endif
+# ifndef P_CPU_ARM_V7
+# define P_CPU_ARM_V7
+# endif
+# ifndef P_CPU_ARM_V8
+# define P_CPU_ARM_V8
+# endif
+# ifndef P_CPU_X86
+# define P_CPU_X86
+# endif
+# ifndef P_CPU_X86_32
+# define P_CPU_X86_32
+# endif
+# ifndef P_CPU_X86_64
+# define P_CPU_X86_64
+# endif
+# ifndef P_CPU_IA64
+# define P_CPU_IA64
+# endif
+# ifndef P_CPU_MIPS
+# define P_CPU_MIPS
+# endif
+# ifndef P_CPU_MIPS_I
+# define P_CPU_MIPS_I
+# endif
+# ifndef P_CPU_MIPS_II
+# define P_CPU_MIPS_II
+# endif
+# ifndef P_CPU_MIPS_III
+# define P_CPU_MIPS_III
+# endif
+# ifndef P_CPU_MIPS_IV
+# define P_CPU_MIPS_IV
+# endif
+# ifndef P_CPU_MIPS_32
+# define P_CPU_MIPS_32
+# endif
+# ifndef P_CPU_MIPS_64
+# define P_CPU_MIPS_64
+# endif
+# ifndef P_CPU_POWER
+# define P_CPU_POWER
+# endif
+# ifndef P_CPU_POWER_32
+# define P_CPU_POWER_32
+# endif
+# ifndef P_CPU_POWER_64
+# define P_CPU_POWER_64
+# endif
+# ifndef P_CPU_SPARC
+# define P_CPU_SPARC
+# endif
+# ifndef P_CPU_SPARC_V8
+# define P_CPU_SPARC_V8
+# endif
+# ifndef P_CPU_SPARC_V9
+# define P_CPU_SPARC_V9
+# endif
+# ifndef P_CPU_HPPA
+# define P_CPU_HPPA
+# endif
+# ifndef P_CPU_HPPA_32
+# define P_CPU_HPPA_32
+# endif
+# ifndef P_CPU_HPPA_64
+# define P_CPU_HPPA_64
+# endif
+#endif
+
+#endif /* PLIBSYS_HEADER_PMACROSCPU_H */
diff --git a/3rdparty/plibsys/src/pmacrosos.h b/3rdparty/plibsys/src/pmacrosos.h
new file mode 100644
index 0000000..c14a27a
--- /dev/null
+++ b/3rdparty/plibsys/src/pmacrosos.h
@@ -0,0 +1,500 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmacrosos.h
+ * @brief OS detection macros
+ * @author Alexander Saprykin
+ *
+ * All the macros are completely independent of any other platform-specific
+ * headers, thus gurantee to work with any compiler under any operating system
+ * in the same way as they are used within the library.
+ *
+ * This family of macros provides OS detection and defines one or several of
+ * P_OS_x macros.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMACROSOS_H
+#define PLIBSYS_HEADER_PMACROSOS_H
+
+/*
+ * List of supported operating systems (P_OS_x):
+ *
+ * DARWIN - Any Darwin based system
+ * DARWIN32 - Any 32-bit Darwin based system
+ * DARWIN64 - Any 64-bit Darwin based system
+ * BSD4 - Any BSD 4.x based system
+ * FREEBSD - FreeBSD
+ * DRAGONFLY - DragonFlyBSD
+ * NETBSD - NetBSD
+ * OPENBSD - OpenBSD
+ * AIX - IBM AIX
+ * HPUX - HP-UX
+ * TRU64 - Tru64
+ * SOLARIS - Sun (Oracle) Solaris
+ * QNX - QNX 4.x
+ * QNX6 - QNX Neutrino 6.x
+ * BB10 - BlackBerry 10
+ * SCO - SCO OpenServer 5/6
+ * UNIXWARE - UnixWare 7
+ * IRIX - SGI IRIX
+ * HAIKU - Haiku
+ * SYLLABLE - Syllable
+ * BEOS - BeOS
+ * OS2 - OS/2
+ * VMS - OpenVMS
+ * AMIGA - AmigaOS
+ * UNIX - Any UNIX BSD/SYSV based system
+ * LINUX - Linux
+ * MAC9 - Mac OS 9 (Classic)
+ * MAC - Any macOS
+ * MAC32 - 32-bit macOS
+ * MAC64 - 64-bit macOS
+ * CYGWIN - Cygwin
+ * MSYS - MSYS
+ * WIN - 32-bit Windows
+ * WIN64 - 64-bit Windows
+ * ANDROID - Android
+ */
+
+/**
+ * @def P_OS_DARWIN
+ * @brief Darwin based operating system (i.e. macOS).
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_DARWIN32
+ * @brief Darwin based 32-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_DARWIN64
+ * @brief Darwin based 64-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_BSD4
+ * @brief BSD 4.x based operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_FREEBSD
+ * @brief FreeBSD operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_DRAGONFLY
+ * @brief DragonFlyBSD operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_NETBSD
+ * @brief NetBSD operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_OPENBSD
+ * @brief OpenBSD operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_AIX
+ * @brief IBM AIX operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_HPUX
+ * @brief HP-UX operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_TRU64
+ * @brief Tru64 operating system.
+ * @since 0.0.2
+ */
+
+/**
+ * @def P_OS_SOLARIS
+ * @brief Sun (Oracle) Solaris operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_QNX
+ * @brief QNX 4.x operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_QNX6
+ * @brief QNX Neutrino 6.x operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_BB10
+ * @brief BlackBerry 10 operating system.
+ * @since 0.0.4
+ */
+
+/**
+ * @def P_OS_SCO
+ * @brief SCO OpenServer operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_UNIXWARE
+ * @brief UnixWare 7 operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_IRIX
+ * @brief SGI's IRIX operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_HAIKU
+ * @brief Haiku operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_SYLLABLE
+ * @brief Syllable operating system.
+ * @since 0.0.2
+ */
+
+/**
+ * @def P_OS_BEOS
+ * @brief BeOS operating system.
+ * @since 0.0.3
+ */
+
+/**
+ * @def P_OS_OS2
+ * @brief OS/2 operating system.
+ * @since 0.0.3
+ */
+
+/**
+ * @def P_OS_VMS
+ * @brief OpenVMS operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_AMIGA
+ * @brief AmigaOS operating system.
+ * @since 0.0.4
+ */
+
+/**
+ * @def P_OS_UNIX
+ * @brief UNIX based operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_LINUX
+ * @brief Linux based operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_MAC9
+ * @brief Apple's Mac OS 9 operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_MAC
+ * @brief Apple's macOS operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_MAC32
+ * @brief Apple's macOS 32-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_MAC64
+ * @brief Apple's macOS 64-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_CYGWIN
+ * @brief Microsoft Windows POSIX runtime environment.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_MSYS
+ * @brief Microsoft Windows POSIX development environment.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_WIN
+ * @brief Microsoft Windows 32-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_WIN64
+ * @brief Microsoft Windows 64-bit operating system.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_OS_ANDROID
+ * @brief Google Android
+ * @since 0.0.4
+ */
+
+#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
+# define P_OS_DARWIN
+# define P_OS_BSD4
+# ifdef __LP64__
+# define P_OS_DARWIN64
+# else
+# define P_OS_DARWIN32
+# endif
+# elif defined(Macintosh) || defined(macintosh)
+# define P_OS_MAC9
+#elif defined(__MSYS__)
+# define P_OS_MSYS
+#elif defined(__CYGWIN__)
+# define P_OS_CYGWIN
+#elif defined(_WIN64) || defined(_M_X64) || defined(_M_AMD64)
+# define P_OS_WIN64
+#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
+# define P_OS_WIN
+#elif defined(__ANDROID__)
+# define P_OS_ANDROID
+# define P_OS_LINUX
+#elif defined(__linux) || defined(__linux__)
+# define P_OS_LINUX
+#elif defined(__FreeBSD__)
+# define P_OS_FREEBSD
+# define P_OS_BSD4
+#elif defined(__DragonFly__)
+# define P_OS_DRAGONFLY
+# define P_OS_BSD4
+#elif defined(__NetBSD__)
+# define P_OS_NETBSD
+# define P_OS_BSD4
+#elif defined(__OpenBSD__)
+# define P_OS_OPENBSD
+# define P_OS_BSD4
+#elif defined(_AIX)
+# define P_OS_AIX
+#elif defined(hpux) || defined(__hpux)
+# define P_OS_HPUX
+#elif defined(__osf__) || defined(__osf)
+# define P_OS_TRU64
+#elif defined(__sun) || defined(sun)
+# define P_OS_SOLARIS
+#elif defined(__QNXNTO__)
+# ifdef __BLACKBERRY10__
+# define P_OS_BB10
+# else
+# define P_OS_QNX6
+# endif
+#elif defined(__QNX__)
+# define P_OS_QNX
+#elif defined(_SCO_DS)
+# define P_OS_SCO
+#elif defined(__USLC__) || defined(__UNIXWARE__)
+# define P_OS_UNIXWARE
+#elif defined(__svr4__) && defined(i386)
+# define P_OS_UNIXWARE
+#elif defined(__sgi) || defined(sgi)
+# define P_OS_IRIX
+#elif defined(__HAIKU__)
+# define P_OS_HAIKU
+#elif defined(__SYLLABLE__)
+# define P_OS_SYLLABLE
+#elif defined(__BEOS__)
+# define P_OS_BEOS
+#elif defined(__OS2__)
+# define P_OS_OS2
+#elif defined(VMS) || defined(__VMS)
+# define P_OS_VMS
+#elif defined(AMIGA) || defined(__amigaos__)
+# define P_OS_AMIGA
+#endif
+
+#ifdef P_OS_WIN64
+# define P_OS_WIN
+#endif
+
+#if defined(P_OS_DARWIN)
+# define P_OS_MAC
+# if defined(P_OS_DARWIN64)
+# define P_OS_MAC64
+# elif defined(P_OS_DARWIN32)
+# define P_OS_MAC32
+# endif
+#endif
+
+#if defined(P_OS_WIN) || defined(P_OS_MAC9) || defined(P_OS_HAIKU) || \
+ defined(P_OS_BEOS) || defined(P_OS_OS2) || defined(P_OS_VMS) || \
+ defined(P_OS_AMIGA)
+# undef P_OS_UNIX
+#elif !defined(P_OS_UNIX)
+# define P_OS_UNIX
+#endif
+
+/* We need this to generate full Doxygen documentation */
+
+#ifdef DOXYGEN
+# ifndef P_OS_DARWIN
+# define P_OS_DARWIN
+# endif
+# ifndef P_OS_DARWIN32
+# define P_OS_DARWIN32
+# endif
+# ifndef P_OS_DARWIN64
+# define P_OS_DARWIN64
+# endif
+# ifndef P_OS_BSD4
+# define P_OS_BSD4
+# endif
+# ifndef P_OS_FREEBSD
+# define P_OS_FREEBSD
+# endif
+# ifndef P_OS_DRAGONFLY
+# define P_OS_DRAGONFLY
+# endif
+# ifndef P_OS_NETBSD
+# define P_OS_NETBSD
+# endif
+# ifndef P_OS_OPENBSD
+# define P_OS_OPENBSD
+# endif
+# ifndef P_OS_AIX
+# define P_OS_AIX
+# endif
+# ifndef P_OS_HPUX
+# define P_OS_HPUX
+# endif
+# ifndef P_OS_TRU64
+# define P_OS_TRU64
+# endif
+# ifndef P_OS_SOLARIS
+# define P_OS_SOLARIS
+# endif
+# ifndef P_OS_QNX
+# define P_OS_QNX
+# endif
+# ifndef P_OS_QNX6
+# define P_OS_QNX6
+# endif
+# ifndef P_OS_BB10
+# define P_OS_BB10
+# endif
+# ifndef P_OS_SCO
+# define P_OS_SCO
+# endif
+# ifndef P_OS_UNIXWARE
+# define P_OS_UNIXWARE
+# endif
+# ifndef P_OS_IRIX
+# define P_OS_IRIX
+# endif
+# ifndef P_OS_HAIKU
+# define P_OS_HAIKU
+# endif
+# ifndef P_OS_SYLLABLE
+# define P_OS_SYLLABLE
+# endif
+# ifndef P_OS_BEOS
+# define P_OS_BEOS
+# endif
+# ifndef P_OS_OS2
+# define P_OS_OS2
+# endif
+# ifndef P_OS_VMS
+# define P_OS_VMS
+# endif
+# ifndef P_OS_AMIGA
+# define P_OS_AMIGA
+# endif
+# ifndef P_OS_UNIX
+# define P_OS_UNIX
+# endif
+# ifndef P_OS_LINUX
+# define P_OS_LINUX
+# endif
+# ifndef P_OS_MAC9
+# define P_OS_MAC9
+# endif
+# ifndef P_OS_MAC
+# define P_OS_MAC
+# endif
+# ifndef P_OS_MAC32
+# define P_OS_MAC32
+# endif
+# ifndef P_OS_MAC64
+# define P_OS_MAC64
+# endif
+# ifndef P_OS_CYGWIN
+# define P_OS_CYGWIN
+# endif
+# ifndef P_OS_MSYS
+# define P_OS_MSYS
+# endif
+# ifndef P_OS_WIN
+# define P_OS_WIN
+# endif
+# ifndef P_OS_WIN64
+# define P_OS_WIN64
+# endif
+# ifndef P_OS_ANDROID
+# define P_OS_ANDROID
+# endif
+#endif
+
+#endif /* PLIBSYS_HEADER_PMACROSOS_H */
diff --git a/3rdparty/plibsys/src/pmain.c b/3rdparty/plibsys/src/pmain.c
new file mode 100644
index 0000000..ad40dfb
--- /dev/null
+++ b/3rdparty/plibsys/src/pmain.c
@@ -0,0 +1,132 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmain.h"
+
+extern void p_mem_init (void);
+extern void p_mem_shutdown (void);
+extern void p_atomic_thread_init (void);
+extern void p_atomic_thread_shutdown (void);
+extern void p_socket_init_once (void);
+extern void p_socket_close_once (void);
+extern void p_uthread_init (void);
+extern void p_uthread_shutdown (void);
+extern void p_cond_variable_init (void);
+extern void p_cond_variable_shutdown (void);
+extern void p_rwlock_init (void);
+extern void p_rwlock_shutdown (void);
+extern void p_time_profiler_init (void);
+extern void p_time_profiler_shutdown (void);
+extern void p_library_loader_init (void);
+extern void p_library_loader_shutdown (void);
+
+static pboolean pp_plibsys_inited = FALSE;
+static pchar pp_plibsys_version[] = PLIBSYS_VERSION_STR;
+
+P_LIB_API void
+p_libsys_init (void)
+{
+ if (P_UNLIKELY (pp_plibsys_inited == TRUE))
+ return;
+
+ pp_plibsys_inited = TRUE;
+
+ p_mem_init ();
+ p_atomic_thread_init ();
+ p_socket_init_once ();
+ p_uthread_init ();
+ p_cond_variable_init ();
+ p_rwlock_init ();
+ p_time_profiler_init ();
+ p_library_loader_init ();
+}
+
+P_LIB_API void
+p_libsys_init_full (const PMemVTable *vtable)
+{
+ if (p_mem_set_vtable (vtable) == FALSE)
+ P_ERROR ("MAIN::p_libsys_init_full: failed to initialize memory table");
+
+ p_libsys_init ();
+}
+
+P_LIB_API void
+p_libsys_shutdown (void)
+{
+ if (P_UNLIKELY (pp_plibsys_inited == FALSE))
+ return;
+
+ pp_plibsys_inited = FALSE;
+
+ p_library_loader_init ();
+ p_time_profiler_shutdown ();
+ p_rwlock_shutdown ();
+ p_cond_variable_shutdown ();
+ p_uthread_shutdown ();
+ p_socket_close_once ();
+ p_atomic_thread_shutdown ();
+ p_mem_shutdown ();
+}
+
+P_LIB_API const pchar *
+p_libsys_version (void)
+{
+ return (const pchar *) pp_plibsys_version;
+}
+
+#ifdef P_OS_WIN
+extern void p_uthread_win32_thread_detach (void);
+
+BOOL WINAPI DllMain (HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved);
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
+{
+ P_UNUSED (hinstDLL);
+ P_UNUSED (lpvReserved);
+
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ p_uthread_win32_thread_detach ();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ break;
+
+ default:
+ ;
+ }
+
+ return TRUE;
+}
+#endif
diff --git a/3rdparty/plibsys/src/pmain.h b/3rdparty/plibsys/src/pmain.h
new file mode 100644
index 0000000..eff615d
--- /dev/null
+++ b/3rdparty/plibsys/src/pmain.h
@@ -0,0 +1,209 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmain.h
+ * @brief Library initialization
+ * @author Alexander Saprykin
+ *
+ * Before using the library you must to initialize it properly. Use
+ * p_libsys_init() to initialize the library. Please note that you need to call
+ * it only once, not in every thread. This call is not MT-safe (because it also
+ * initializes the threading subsystem itself), so it is best to place it in the
+ * program's main thread, when the program starts.
+ *
+ * The only difference between p_libsys_init() and p_libsys_init_full() is that
+ * the latter one allows to setup memory management routines before doing any
+ * internal library call. This way you can ensure to use provided memory
+ * management everywhere (even for library initialization).
+ *
+ * When you do not need the library anymore release used resourses with the
+ * p_libsys_shutdown() routine. You should only call it once, too. This call is
+ * not MT-safe (because it also deinitializes the threading subsystem itself),
+ * so it is best to place it in the program's main thread, when the program
+ * finishes.
+ *
+ * It is not recommended to call the initialization and deinitialization
+ * routines on Windows in the DllMain() call because it may require libraries
+ * other than kernel32.dll.
+ */
+
+/**
+ * @mainpage
+ * Basic
+ * - @link
+ * pmain.h Library initialization
+ * @endlink
+ * - @link
+ * ptypes.h Data types
+ * @endlink
+ * - @link
+ * pmacroscpu.h CPU detection macros
+ * @endlink
+ * - @link
+ * pmacrosos.h OS detection macros
+ * @endlink
+ * - @link
+ * pmacroscompiler.h Compiler detection macros
+ * @endlink
+ * - @link
+ * pmacros.h Miscellaneous macros
+ * @endlink
+ * - @link
+ * pstring.h Strings
+ * @endlink
+ *
+ * System
+ * - @link
+ * pmem.h Memory management
+ * @endlink
+ * - @link
+ * pprocess.h Process
+ * @endlink
+ * - @link
+ * plibraryloader.h Shared library loader
+ * @endlink
+ * - @link
+ * ptimeprofiler.h Time profiler
+ * @endlink
+ * - @link
+ * perror.h Errors
+ * @endlink
+ *
+ * Data structures
+ * - @link
+ * plist.h Singly linked list
+ * @endlink
+ * - @link
+ * phashtable.h Hash table
+ * @endlink
+ * - @link
+ * pcryptohash.h Cryptographic hash
+ * @endlink
+ * - @link
+ * ptree.h Binary search tree
+ * @endlink
+ *
+ * Multithreading
+ * - @link
+ * puthread.h Thread
+ * @endlink
+ * - @link
+ * pmutex.h Mutex
+ * @endlink
+ * - @link
+ * pcondvariable.h Condition variable
+ * @endlink
+ * - @link
+ * prwlock.h Read-write lock
+ * @endlink
+ * - @link
+ * pspinlock.h Spinlock
+ * @endlink
+ * - @link
+ * patomic.h Atomic operations
+ * @endlink
+ *
+ * Interprocess communication
+ * - @link
+ * psemaphore.h Semaphore
+ * @endlink
+ * - @link
+ * pshm.h Shared memory
+ * @endlink
+ * - @link
+ * pshmbuffer.h Shared memory buffer
+ * @endlink
+ *
+ * Networking
+ * - @link
+ * psocketaddress.h Socket address
+ * @endlink
+ * - @link
+ * psocket.h Socket
+ * @endlink
+ *
+ * File and directories
+ * - @link
+ * pfile.h Files
+ * @endlink
+ * - @link
+ * pdir.h Directories
+ * @endlink
+ * - @link
+ * pinifile.h INI file parser
+ * @endlink
+ *
+ * Stack
+ * - @link
+ * pstdarg.h Variable number of arguments
+ * @endlink
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMAIN_H
+#define PLIBSYS_HEADER_PMAIN_H
+
+#include <pmacros.h>
+#include <pmem.h>
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Initializes library resources.
+ * @since 0.0.1
+ */
+P_LIB_API void p_libsys_init (void);
+
+/**
+ * @brief Initializes library resources along with the memory table.
+ * @param vtable Memory management table.
+ * @since 0.0.1
+ */
+P_LIB_API void p_libsys_init_full (const PMemVTable *vtable);
+
+/**
+ * @brief Frees library resources. You should stop using any of the library
+ * routines after calling this one.
+ * @since 0.0.1
+ */
+P_LIB_API void p_libsys_shutdown (void);
+
+/**
+ * @brief Gets the library version against which it was compiled at run-time.
+ * @return Library version.
+ * @since 0.0.1
+ * @note This version may differ from the version the application was compiled
+ * against.
+ * @sa #PLIBSYS_VERSION, #PLIBSYS_VERSION_STR, #PLIBSYS_VERSION_CHECK
+ */
+P_LIB_API const pchar * p_libsys_version (void);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PMAIN_H */
diff --git a/3rdparty/plibsys/src/pmem.c b/3rdparty/plibsys/src/pmem.c
new file mode 100644
index 0000000..04701fa
--- /dev/null
+++ b/3rdparty/plibsys/src/pmem.c
@@ -0,0 +1,357 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "perror.h"
+#include "pmem.h"
+#include "perror-private.h"
+#include "psysclose-private.h"
+
+#ifndef P_OS_WIN
+# if defined (P_OS_BEOS)
+# include <be/kernel/OS.h>
+# elif defined (P_OS_OS2)
+# define INCL_DOSMEMMGR
+# define INCL_DOSERRORS
+# include <os2.h>
+# elif !defined (P_OS_AMIGA)
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# endif
+#endif
+
+static pboolean p_mem_table_inited = FALSE;
+static PMemVTable p_mem_table;
+
+void
+p_mem_init (void)
+{
+ if (P_UNLIKELY (p_mem_table_inited == TRUE))
+ return;
+
+ p_mem_restore_vtable ();
+}
+
+void
+p_mem_shutdown (void)
+{
+ if (P_UNLIKELY (!p_mem_table_inited))
+ return;
+
+ p_mem_table.malloc = NULL;
+ p_mem_table.realloc = NULL;
+ p_mem_table.free = NULL;
+
+ p_mem_table_inited = FALSE;
+}
+
+P_LIB_API ppointer
+p_malloc (psize n_bytes)
+{
+ if (P_LIKELY (n_bytes > 0))
+ return p_mem_table.malloc (n_bytes);
+ else
+ return NULL;
+}
+
+P_LIB_API ppointer
+p_malloc0 (psize n_bytes)
+{
+ ppointer ret;
+
+ if (P_LIKELY (n_bytes > 0)) {
+ if (P_UNLIKELY ((ret = p_mem_table.malloc (n_bytes)) == NULL))
+ return NULL;
+
+ memset (ret, 0, n_bytes);
+ return ret;
+ } else
+ return NULL;
+}
+
+P_LIB_API ppointer
+p_realloc (ppointer mem, psize n_bytes)
+{
+ if (P_UNLIKELY (n_bytes == 0))
+ return NULL;
+
+ if (P_UNLIKELY (mem == NULL))
+ return p_mem_table.malloc (n_bytes);
+ else
+ return p_mem_table.realloc (mem, n_bytes);
+}
+
+P_LIB_API void
+p_free (ppointer mem)
+{
+ if (P_LIKELY (mem != NULL))
+ p_mem_table.free (mem);
+}
+
+P_LIB_API pboolean
+p_mem_set_vtable (const PMemVTable *table)
+{
+ if (P_UNLIKELY (table == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (table->free == NULL || table->malloc == NULL || table->realloc == NULL))
+ return FALSE;
+
+ p_mem_table.malloc = table->malloc;
+ p_mem_table.realloc = table->realloc;
+ p_mem_table.free = table->free;
+
+ p_mem_table_inited = TRUE;
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_mem_restore_vtable (void)
+{
+ p_mem_table.malloc = (ppointer (*)(psize)) malloc;
+ p_mem_table.realloc = (ppointer (*)(ppointer, psize)) realloc;
+ p_mem_table.free = (void (*)(ppointer)) free;
+
+ p_mem_table_inited = TRUE;
+}
+
+P_LIB_API ppointer
+p_mem_mmap (psize n_bytes,
+ PError **error)
+{
+ ppointer addr;
+#if defined (P_OS_WIN)
+ HANDLE hdl;
+#elif defined (P_OS_BEOS)
+ area_id area;
+#elif defined (P_OS_OS2)
+ APIRET ulrc;
+#elif !defined (P_OS_AMIGA)
+ int fd;
+ int map_flags = MAP_PRIVATE;
+#endif
+
+ if (P_UNLIKELY (n_bytes == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+#if defined (P_OS_WIN)
+ if (P_UNLIKELY ((hdl = CreateFileMappingA (INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ (DWORD) n_bytes,
+ NULL)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call CreateFileMapping() to create file mapping");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((addr = MapViewOfFile (hdl,
+ FILE_MAP_READ | FILE_MAP_WRITE,
+ 0,
+ 0,
+ n_bytes)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call MapViewOfFile() to map file view");
+ CloseHandle (hdl);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (!CloseHandle (hdl))) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call CloseHandle() to close file mapping");
+ UnmapViewOfFile (addr);
+ return NULL;
+ }
+#elif defined (P_OS_BEOS)
+ if (P_LIKELY ((n_bytes % B_PAGE_SIZE)) != 0)
+ n_bytes = (n_bytes / B_PAGE_SIZE + 1) * B_PAGE_SIZE;
+
+ area = create_area ("", &addr, B_ANY_ADDRESS, n_bytes, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
+
+ if (P_UNLIKELY (area < B_NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call create_area() to create memory area");
+ return NULL;
+ }
+#elif defined (P_OS_OS2)
+ if (P_UNLIKELY ((ulrc = DosAllocMem ((PPVOID) &addr,
+ (ULONG) n_bytes,
+ PAG_READ | PAG_WRITE | PAG_COMMIT |
+ OBJ_ANY)) != NO_ERROR)) {
+ /* Try to remove OBJ_ANY */
+ if (P_UNLIKELY ((ulrc = DosAllocMem ((PPVOID) &addr,
+ (ULONG) n_bytes,
+ PAG_READ | PAG_WRITE)) != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ ulrc,
+ "Failed to call DosAllocMemory() to alocate memory");
+ return NULL;
+ }
+ }
+#elif defined (P_OS_AMIGA)
+ addr = malloc (n_bytes);
+
+ if (P_UNLIKELY (addr == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to allocate system memory");
+ return NULL;
+ }
+#else
+# if !defined (PLIBSYS_MMAP_HAS_MAP_ANONYMOUS) && !defined (PLIBSYS_MMAP_HAS_MAP_ANON)
+ if (P_UNLIKELY ((fd = open ("/dev/zero", O_RDWR | O_EXCL, 0754)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to open /dev/zero for file mapping");
+ return NULL;
+ }
+# else
+ fd = -1;
+# endif
+
+# ifdef PLIBSYS_MMAP_HAS_MAP_ANONYMOUS
+ map_flags |= MAP_ANONYMOUS;
+# elif defined (PLIBSYS_MMAP_HAS_MAP_ANON)
+ map_flags |= MAP_ANON;
+# endif
+
+ if (P_UNLIKELY ((addr = mmap (NULL,
+ n_bytes,
+ PROT_READ | PROT_WRITE,
+ map_flags,
+ fd,
+ 0)) == (void *) -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call mmap() to create file mapping");
+# if !defined (PLIBSYS_MMAP_HAS_MAP_ANONYMOUS) && !defined (PLIBSYS_MMAP_HAS_MAP_ANON)
+ if (P_UNLIKELY (p_sys_close (fd) != 0))
+ P_WARNING ("PMem::p_mem_mmap: failed to close file descriptor to /dev/zero");
+# endif
+ return NULL;
+ }
+
+# if !defined (PLIBSYS_MMAP_HAS_MAP_ANONYMOUS) && !defined (PLIBSYS_MMAP_HAS_MAP_ANON)
+ if (P_UNLIKELY (p_sys_close (fd) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to close /dev/zero handle");
+ munmap (addr, n_bytes);
+ return NULL;
+ }
+# endif
+#endif
+
+ return addr;
+}
+
+P_LIB_API pboolean
+p_mem_munmap (ppointer mem,
+ psize n_bytes,
+ PError **error)
+{
+#if defined (P_OS_BEOS)
+ area_id area;
+#elif defined (P_OS_OS2)
+ APIRET ulrc;
+#elif defined (P_OS_AMIGA)
+ P_UNUSED (n_bytes);
+ P_UNUSED (error);
+#endif
+
+ if (P_UNLIKELY (mem == NULL || n_bytes == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+#if defined (P_OS_WIN)
+ if (P_UNLIKELY (UnmapViewOfFile (mem) == 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call UnmapViewOfFile() to remove file mapping");
+#elif defined (P_OS_BEOS)
+ if (P_UNLIKELY ((area = area_for (mem)) == B_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call area_for() to find allocated memory area");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((delete_area (area)) != B_OK)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call delete_area() to remove memory area");
+#elif defined (P_OS_OS2)
+ if (P_UNLIKELY ((ulrc = DosFreeMem ((PVOID) mem)) != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system ((pint) ulrc),
+ ulrc,
+ "Failed to call DosFreeMem() to free memory");
+#elif defined (P_OS_AMIGA)
+ free (mem);
+
+ if (P_UNLIKELY (FALSE)) {
+#else
+ if (P_UNLIKELY (munmap (mem, n_bytes) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_io (),
+ p_error_get_last_system (),
+ "Failed to call munmap() to remove file mapping");
+#endif
+ return FALSE;
+ } else
+ return TRUE;
+}
diff --git a/3rdparty/plibsys/src/pmem.h b/3rdparty/plibsys/src/pmem.h
new file mode 100644
index 0000000..3643942
--- /dev/null
+++ b/3rdparty/plibsys/src/pmem.h
@@ -0,0 +1,191 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmem.h
+ * @brief Memory management
+ * @author Alexander Saprykin
+ *
+ * Usually the system routines for memory management are used: malloc(),
+ * realloc(), free() and so on. But it is highly encouraged to use a more
+ * general approach: p_malloc(), p_malloc0(), p_realloc() and p_free() family of
+ * memory management routines. It gives you several advantages:
+ * - automatical checking of all input parameters for the NULL values;
+ * - ability to use a custom memory allocator.
+ * You can also mix these two families of calls, but it is not recommended.
+ *
+ * By default p_* routines are mapped to system calls, thus only NULL-checking
+ * is additionally performed. If you want to use the custom memory allocator,
+ * then fill in #PMemVTable structure and pass it to the p_mem_set_vtable(). To
+ * restore system calls back use p_mem_restore_vtable().
+ *
+ * Be careful when using the custom memory allocator: all memory chunks
+ * allocated with the custom allocator must be freed with the same allocator. If
+ * the custom allocator was installed after the library initialization call
+ * p_libsys_init() then you must to restore the original allocator before
+ * calling p_libsys_shutdown().
+ *
+ * Use p_mem_mmap() to allocate system memory using memory mapping and
+ * p_mem_munmap() to release the mapped memory. This type of allocated memory
+ * is not backed physically (does not consume any physical storage) by operating
+ * system. It means that every memory page within the allocated region will be
+ * committed to physical backend only when you first touch it. Until that
+ * untouched pages will be reserved for future usage. It can be useful when
+ * dealing with large memory blocks which should be filled with data on demand,
+ * i.e. custom memory allocator can request a large block first, and then it
+ * allocates chunks of memory within the block upon request.
+ *
+ * @note OS/2 supports non-backed memory pages allocation, but in a specific
+ * way: an exception handler to control access to uncommitted pages must be
+ * allocated on the stack of each thread before using the mapped memory. To
+ * unify the behaviour, on OS/2 all memory mapped allocations are already
+ * committed to the backing storage.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMEM_H
+#define PLIBSYS_HEADER_PMEM_H
+
+#include <ptypes.h>
+#include <pmacros.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Memory management table. */
+typedef struct PMemVTable_ {
+ ppointer (*malloc) (psize n_bytes); /**< malloc() implementation. */
+ ppointer (*realloc) (ppointer mem,
+ psize n_bytes); /**< realloc() implementation. */
+ void (*free) (ppointer mem); /**< free() implementation. */
+} PMemVTable;
+
+/**
+ * @brief Allocates a memory block for the specified number of bytes.
+ * @param n_bytes Size of the memory block in bytes.
+ * @return Pointer to a newly allocated memory block in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_malloc (psize n_bytes);
+
+/**
+ * @brief Allocates a memory block for the specified number of bytes and fills
+ * it with zeros.
+ * @param n_bytes Size of the memory block in bytes.
+ * @return Pointer to a newly allocated memory block filled with zeros in case
+ * of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_malloc0 (psize n_bytes);
+
+/**
+ * @brief Changes the memory block size.
+ * @param mem Pointer to the memory block.
+ * @param n_bytes New size for @a mem block.
+ * @return Pointer to a newlly allocated memory block in case of success (if
+ * @a mem is NULL then it acts like p_malloc()), NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_realloc (ppointer mem,
+ psize n_bytes);
+
+/**
+ * @brief Frees a memory block by its pointer.
+ * @param mem Pointer to the memory block to free.
+ * @since 0.0.1
+ *
+ * You should only call this function for the pointers which were obtained using
+ * the p_malloc(), p_malloc0() and p_realloc() routines, otherwise behavior is
+ * unpredictable.
+ *
+ * Checks the pointer for the NULL value.
+ */
+P_LIB_API void p_free (ppointer mem);
+
+/**
+ * @brief Sets custom memory management routines.
+ * @param table Table of the memory routines to use.
+ * @return TRUE if the table was accepted, FALSE otherwise.
+ * @note All members of @a table must be non-NULL.
+ * @note This call is not thread-safe.
+ * @warning Do not forget to set the original memory management routines before
+ * calling p_libsys_shutdown() if you have used p_mem_set_vtable() after the
+ * library initialization.
+ * @since 0.0.1
+ *
+ * In most cases you do not need to use this function. Use it only when you know
+ * what are you doing!
+ */
+P_LIB_API pboolean p_mem_set_vtable (const PMemVTable *table);
+
+/**
+ * @brief Restores system memory management routines.
+ * @note This call is not thread-safe.
+ * @since 0.0.1
+ *
+ * The following system routines are restored: malloc(), free(), realloc().
+ */
+P_LIB_API void p_mem_restore_vtable (void);
+
+/**
+ * @brief Gets a memory mapped block from the system.
+ * @param n_bytes Size of the memory block in bytes.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to the allocated memory block in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ *
+ * Note that some systems can allocate memory only in chunks of the page size,
+ * so if @a n_bytes is less than the page size it will try to allocate a chunk
+ * of memory equal to the page size instead.
+ *
+ * On most systems returned memory is mapped to the null or swap device.
+ *
+ * @warning On OS/2 returned memory is mapped to physical storage and can be
+ * swapped.
+ */
+P_LIB_API ppointer p_mem_mmap (psize n_bytes,
+ PError **error);
+
+/**
+ * @brief Unmaps memory back to the system.
+ * @param mem Pointer to a memory block previously allocated using the
+ * p_mem_mmap() call.
+ * @param n_bytes Size of the memory block in bytes.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_mem_munmap (ppointer mem,
+ psize n_bytes,
+ PError **error);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PMEM_H */
diff --git a/3rdparty/plibsys/src/pmutex-amiga.c b/3rdparty/plibsys/src/pmutex-amiga.c
new file mode 100644
index 0000000..0c1216a
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-amiga.c
@@ -0,0 +1,101 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+
+#include <exec/exectags.h>
+#include <proto/exec.h>
+
+typedef APTR mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->hdl = IExec->AllocSysObjectTags (ASOT_MUTEX, ASOMUTEX_Recursive, TRUE, TAG_END);
+
+ if (P_UNLIKELY (ret->hdl == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: AllocSysObjectTags() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ IExec->MutexObtain (mutex->hdl);
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return IExec->MutexAttempt (mutex->hdl);
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ IExec->MutexRelease (mutex->hdl);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ IExec->FreeSysObject (ASOT_MUTEX, mutex->hdl);
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-atheos.c b/3rdparty/plibsys/src/pmutex-atheos.c
new file mode 100644
index 0000000..352e5c5
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-atheos.c
@@ -0,0 +1,111 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include <atheos/semaphore.h>
+
+typedef sem_id mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->hdl = create_semaphore ("", 1, 0)) < 0)) {
+ P_ERROR ("PMutex::p_mutex_new: create_semaphore() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ status_t ret_status;
+
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ while ((ret_status = lock_semaphore (mutex->hdl)) == EINTR)
+ ;
+
+ if (P_LIKELY (ret_status == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_lock: lock_semaphore() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return (lock_semaphore_x (mutex->hdl, 1, 0, 0)) == 0 ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (unlock_semaphore (mutex->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_unlock: unlock_semaphore() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ if (P_UNLIKELY (delete_semaphore (mutex->hdl) != 0))
+ P_ERROR ("PMutex::p_mutex_free: delete_semaphore() failed");
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-beos.c b/3rdparty/plibsys/src/pmutex-beos.c
new file mode 100644
index 0000000..c16bf8b
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-beos.c
@@ -0,0 +1,110 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+
+#include <kernel/OS.h>
+
+typedef sem_id mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->hdl = create_sem (1, "")) < B_OK)) {
+ P_ERROR ("PMutex::p_mutex_new: create_sem() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ status_t ret_status;
+
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ while ((ret_status = acquire_sem (mutex->hdl)) == B_INTERRUPTED)
+ ;
+
+ if (P_LIKELY (ret_status == B_NO_ERROR))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_lock: acquire_sem() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return (acquire_sem_etc (mutex->hdl, 1, B_RELATIVE_TIMEOUT, 0)) == B_NO_ERROR ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (release_sem (mutex->hdl) == B_NO_ERROR))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_unlock: release_sem() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ if (P_UNLIKELY (delete_sem (mutex->hdl) != B_NO_ERROR))
+ P_ERROR ("PMutex::p_mutex_free: delete_sem() failed");
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-none.c b/3rdparty/plibsys/src/pmutex-none.c
new file mode 100644
index 0000000..1bc9b50
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-none.c
@@ -0,0 +1,66 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmutex.h"
+
+#include <stdlib.h>
+
+struct PMutex_ {
+ pint hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ return NULL;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ P_UNUSED (mutex);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ P_UNUSED (mutex);
+
+ return FALSE;
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ P_UNUSED (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-os2.c b/3rdparty/plibsys/src/pmutex-os2.c
new file mode 100644
index 0000000..1040044
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-os2.c
@@ -0,0 +1,112 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSERRORS
+#include <os2.h>
+
+typedef HMTX mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (DosCreateMutexSem (NULL, (PHMTX) &ret->hdl, 0, FALSE) != NO_ERROR)) {
+ P_ERROR ("PMutex::p_mutex_new: DosCreateMutexSem() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ APIRET ulrc;
+
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ while ((ulrc = DosRequestMutexSem (mutex->hdl, SEM_INDEFINITE_WAIT)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_LIKELY (ulrc == NO_ERROR))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_lock: DosRequestMutexSem() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return (DosRequestMutexSem (mutex->hdl, SEM_IMMEDIATE_RETURN)) == NO_ERROR ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (DosReleaseMutexSem (mutex->hdl) == NO_ERROR))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_unlock: DosReleaseMutexSem() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ if (P_UNLIKELY (DosCloseMutexSem (mutex->hdl) != NO_ERROR))
+ P_ERROR ("PMutex::p_mutex_free: DosCloseMutexSem() failed");
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-posix.c b/3rdparty/plibsys/src/pmutex-posix.c
new file mode 100644
index 0000000..4c471cb
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-posix.c
@@ -0,0 +1,104 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+
+typedef pthread_mutex_t mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pthread_mutex_init (&ret->hdl, NULL) != 0)) {
+ P_ERROR ("PMutex::p_mutex_new: pthread_mutex_init() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (pthread_mutex_lock (&mutex->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_lock: pthread_mutex_lock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return (pthread_mutex_trylock (&mutex->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (pthread_mutex_unlock (&mutex->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_unlock: pthread_mutex_unlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ if (P_UNLIKELY (pthread_mutex_destroy (&mutex->hdl) != 0))
+ P_ERROR ("PMutex::p_mutex_free: pthread_mutex_destroy() failed");
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-solaris.c b/3rdparty/plibsys/src/pmutex-solaris.c
new file mode 100644
index 0000000..bb7adda
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-solaris.c
@@ -0,0 +1,105 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+#include <synch.h>
+#include <thread.h>
+
+typedef mutex_t mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if ((P_UNLIKELY (ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (mutex_init (&ret->hdl, USYNC_THREAD, NULL) != 0)) {
+ P_ERROR ("PMutex::p_mutex_new: mutex_init() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (mutex_lock (&mutex->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_lock: mutex_lock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return (mutex_trylock (&mutex->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ if (P_LIKELY (mutex_unlock (&mutex->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PMutex::p_mutex_unlock: mutex_unlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ if (P_UNLIKELY (mutex_destroy (&mutex->hdl) != 0))
+ P_ERROR ("PMutex::p_mutex_unlock: mutex_destroy() failed");
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex-win.c b/3rdparty/plibsys/src/pmutex-win.c
new file mode 100644
index 0000000..2a801b6
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex-win.c
@@ -0,0 +1,92 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+
+#include <stdlib.h>
+
+typedef CRITICAL_SECTION mutex_hdl;
+
+struct PMutex_ {
+ mutex_hdl hdl;
+};
+
+P_LIB_API PMutex *
+p_mutex_new (void)
+{
+ PMutex *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PMutex))) == NULL)) {
+ P_ERROR ("PMutex::p_mutex_new: failed to allocate memory");
+ return NULL;
+ }
+
+ InitializeCriticalSection (&ret->hdl);
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_mutex_lock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ EnterCriticalSection (&mutex->hdl);
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_mutex_trylock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ return TryEnterCriticalSection (&mutex->hdl) != 0 ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_mutex_unlock (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return FALSE;
+
+ LeaveCriticalSection (&mutex->hdl);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_mutex_free (PMutex *mutex)
+{
+ if (P_UNLIKELY (mutex == NULL))
+ return;
+
+ DeleteCriticalSection (&mutex->hdl);
+
+ p_free (mutex);
+}
diff --git a/3rdparty/plibsys/src/pmutex.h b/3rdparty/plibsys/src/pmutex.h
new file mode 100644
index 0000000..449a652
--- /dev/null
+++ b/3rdparty/plibsys/src/pmutex.h
@@ -0,0 +1,136 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pmutex.h
+ * @brief Mutex routines
+ * @author Alexander Saprykin
+ *
+ * A mutex is a mutual exclusive (hence mutex) synchronization primitive which
+ * allows access to a critical section only to one of the concurrently running
+ * threads. It is used to protected shared data structures from concurrent
+ * modifications which could lead to unpredictable behavior.
+ *
+ * When entering a critical section a thread must call p_mutex_lock() to get a
+ * lock. If another thread is already holding the lock all other threads will
+ * be suspended until the lock is released with p_mutex_unlock(). After
+ * releasing the lock one of the waiting threads is resumed to continue
+ * execution. On most systems it is not specified whether a mutex waiting queue
+ * is fair (FIFO) or not.
+ *
+ * The typical mutex usage:
+ * @code
+ * p_mutex_lock (mutex);
+ *
+ * ... code in critical section ...
+ *
+ * p_mutex_unlock (mutex);
+ * @endcode
+ * You can also think of the mutex as a binary semaphore.
+ *
+ * It is implementation dependent whether recursive locking or non-locked mutex
+ * unlocking is allowed, but such actions can lead to unpredictable behavior.
+ * Do not rely on such behavior in cross-platform applications.
+ *
+ * This is the thread scoped mutex implementation. You could not share this
+ * mutex outside the process adress space, but you can share it between the
+ * threads of the same process.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PMUTEX_H
+#define PLIBSYS_HEADER_PMUTEX_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Mutex opaque data structure. */
+typedef struct PMutex_ PMutex;
+
+/**
+ * @brief Creates a new #PMutex object.
+ * @return Pointer to a newly created #PMutex object.
+ * @since 0.0.1
+ */
+P_LIB_API PMutex * p_mutex_new (void);
+
+/**
+ * @brief Locks a mutex.
+ * @param mutex #PMutex to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock the mutex recursively - it may lead to an application
+ * deadlock (implementation dependent).
+ *
+ * Forces the calling thread to sleep until @a mutex becomes available for
+ * locking.
+ */
+P_LIB_API pboolean p_mutex_lock (PMutex *mutex);
+
+/**
+ * @brief Tries to lock a mutex immediately.
+ * @param mutex #PMutex to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock the mutex recursively - it may lead to an application
+ * deadlock (implementation dependent).
+ *
+ * Tries to lock @a mutex and returns immediately if it is not available for
+ * locking.
+ */
+P_LIB_API pboolean p_mutex_trylock (PMutex *mutex);
+
+/**
+ * @brief Releases a locked mutex.
+ * @param mutex #PMutex to release.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not use this function on non-locked mutexes - behavior may be
+ * unpredictable.
+ *
+ * If @a mutex was previously locked then it becomes unlocked.
+ *
+ * It's implementation dependent whether only the same thread can lock and
+ * unlock the same mutex.
+ */
+P_LIB_API pboolean p_mutex_unlock (PMutex *mutex);
+
+/**
+ * @brief Frees #PMutex object.
+ * @param mutex #PMutex to free.
+ * @since 0.0.1
+ * @warning It doesn't unlock @a mutex before freeing memory, so you should do
+ * it manually.
+ */
+P_LIB_API void p_mutex_free (PMutex *mutex);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PMUTEX_H */
diff --git a/3rdparty/plibsys/src/pprocess.c b/3rdparty/plibsys/src/pprocess.c
new file mode 100644
index 0000000..d509230
--- /dev/null
+++ b/3rdparty/plibsys/src/pprocess.c
@@ -0,0 +1,61 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pprocess.h"
+
+#ifndef P_OS_WIN
+# include <sys/types.h>
+# include <signal.h>
+# include <unistd.h>
+#endif
+
+P_LIB_API puint32
+p_process_get_current_pid (void)
+{
+#ifdef P_OS_WIN
+ return (puint32) GetCurrentProcessId ();
+#else
+ return (puint32) getpid ();
+#endif
+}
+
+P_LIB_API pboolean
+p_process_is_running (puint32 pid)
+{
+#ifdef P_OS_WIN
+ HANDLE proc;
+ DWORD ret;
+
+ if ((proc = OpenProcess (SYNCHRONIZE, FALSE, pid)) == NULL)
+ return FALSE;
+
+ ret = WaitForSingleObject (proc, 0);
+ CloseHandle (proc);
+
+ return ret == WAIT_TIMEOUT;
+#else
+ return kill ((pid_t) pid, 0) == 0;
+#endif
+}
diff --git a/3rdparty/plibsys/src/pprocess.h b/3rdparty/plibsys/src/pprocess.h
new file mode 100644
index 0000000..272bbb5
--- /dev/null
+++ b/3rdparty/plibsys/src/pprocess.h
@@ -0,0 +1,69 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pprocess.h
+ * @brief Process information
+ * @author Alexander Saprykin
+ *
+ * A process is an executing unit in an operating system with its own address
+ * space. Every process can be identified with a unique identifier called PID.
+ * To get a PID of the currently running process call
+ * p_process_get_current_pid(). To check whether a process with a given PID is
+ * running up use p_process_is_running().
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PPROCESS_H
+#define PLIBSYS_HEADER_PPROCESS_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Gets a PID of the calling process.
+ * @return PID of the calling process.
+ * @since 0.0.1
+ */
+P_LIB_API puint32 p_process_get_current_pid (void);
+
+/**
+ * @brief Checks whether a process with a given PID is running or not.
+ * @param pid PID to check for.
+ * @return TRUE if the process with the given PID exists and is running up,
+ * FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_process_is_running (puint32 pid);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PPROCESS_H */
+
diff --git a/3rdparty/plibsys/src/prwlock-general.c b/3rdparty/plibsys/src/prwlock-general.c
new file mode 100644
index 0000000..5d79ed1
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock-general.c
@@ -0,0 +1,326 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+#include "pcondvariable.h"
+#include "prwlock.h"
+
+#include <stdlib.h>
+
+#define P_RWLOCK_SET_READERS(lock, readers) (((lock) & (~0x00007FFF)) | (readers))
+#define P_RWLOCK_READER_COUNT(lock) ((lock) & 0x00007FFF)
+#define P_RWLOCK_SET_WRITERS(lock, writers) (((lock) & (~0x3FFF8000)) | ((writers) << 15))
+#define P_RWLOCK_WRITER_COUNT(lock) (((lock) & 0x3FFF8000) >> 15)
+
+struct PRWLock_ {
+ PMutex *mutex;
+ PCondVariable *read_cv;
+ PCondVariable *write_cv;
+ puint32 active_threads;
+ puint32 waiting_threads;
+};
+
+P_LIB_API PRWLock *
+p_rwlock_new (void)
+{
+ PRWLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PRWLock))) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->mutex = p_mutex_new ()) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate mutex");
+ p_free (ret);
+ }
+
+ if (P_UNLIKELY ((ret->read_cv = p_cond_variable_new ()) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate condition variable for read");
+ p_mutex_free (ret->mutex);
+ p_free (ret);
+ }
+
+ if (P_UNLIKELY ((ret->write_cv = p_cond_variable_new ()) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate condition variable for write");
+ p_cond_variable_free (ret->read_cv);
+ p_mutex_free (ret->mutex);
+ p_free (ret);
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_lock (PRWLock *lock)
+{
+ pboolean wait_ok;
+
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_lock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ wait_ok = TRUE;
+
+ if (P_RWLOCK_WRITER_COUNT (lock->active_threads)) {
+ lock->waiting_threads = P_RWLOCK_SET_READERS (lock->waiting_threads,
+ P_RWLOCK_READER_COUNT (lock->waiting_threads) + 1);
+
+ while (P_RWLOCK_WRITER_COUNT (lock->active_threads)) {
+ wait_ok = p_cond_variable_wait (lock->read_cv, lock->mutex);
+
+ if (P_UNLIKELY (wait_ok == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_lock: p_cond_variable_wait() failed");
+ break;
+ }
+ }
+
+ lock->waiting_threads = P_RWLOCK_SET_READERS (lock->waiting_threads,
+ P_RWLOCK_READER_COUNT (lock->waiting_threads) - 1);
+ }
+
+ if (P_LIKELY (wait_ok == TRUE))
+ lock->active_threads = P_RWLOCK_SET_READERS (lock->active_threads,
+ P_RWLOCK_READER_COUNT (lock->active_threads) + 1);
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_lock: p_mutex_unlock() failed");
+ return FALSE;
+ }
+
+ return wait_ok;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_trylock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ if (P_RWLOCK_WRITER_COUNT (lock->active_threads)) {
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE))
+ P_ERROR ("PRWLock::p_rwlock_reader_trylock: p_mutex_unlock() failed(1)");
+
+ return FALSE;
+ }
+
+ lock->active_threads = P_RWLOCK_SET_READERS (lock->active_threads,
+ P_RWLOCK_READER_COUNT (lock->active_threads) + 1);
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_trylock: p_mutex_unlock() failed(2)");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_unlock (PRWLock *lock)
+{
+ puint32 reader_count;
+ pboolean signal_ok;
+
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_unlock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ reader_count = P_RWLOCK_READER_COUNT (lock->active_threads);
+
+ if (P_UNLIKELY (reader_count == 0)) {
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE))
+ P_ERROR ("PRWLock::p_rwlock_reader_unlock: p_mutex_unlock() failed(1)");
+
+ return TRUE;
+ }
+
+ lock->active_threads = P_RWLOCK_SET_READERS (lock->active_threads, reader_count - 1);
+
+ signal_ok = TRUE;
+
+ if (reader_count == 1 && P_RWLOCK_WRITER_COUNT (lock->waiting_threads))
+ signal_ok = p_cond_variable_signal (lock->write_cv);
+
+ if (P_UNLIKELY (signal_ok == FALSE))
+ P_ERROR ("PRWLock::p_rwlock_reader_unlock: p_cond_variable_signal() failed");
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_reader_unlock: p_mutex_unlock() failed(2)");
+ return FALSE;
+ }
+
+ return signal_ok;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_lock (PRWLock *lock)
+{
+ pboolean wait_ok;
+
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_lock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ wait_ok = TRUE;
+
+ if (lock->active_threads) {
+ lock->waiting_threads = P_RWLOCK_SET_WRITERS (lock->waiting_threads,
+ P_RWLOCK_WRITER_COUNT (lock->waiting_threads) + 1);
+
+ while (lock->active_threads) {
+ wait_ok = p_cond_variable_wait (lock->write_cv, lock->mutex);
+
+ if (P_UNLIKELY (wait_ok == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_lock: p_cond_variable_wait() failed");
+ break;
+ }
+ }
+
+ lock->waiting_threads = P_RWLOCK_SET_WRITERS (lock->waiting_threads,
+ P_RWLOCK_WRITER_COUNT (lock->waiting_threads) - 1);
+ }
+
+ if (P_LIKELY (wait_ok == TRUE))
+ lock->active_threads = P_RWLOCK_SET_WRITERS (lock->active_threads, 1);
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_lock: p_mutex_unlock() failed");
+ return FALSE;
+ }
+
+ return wait_ok;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_trylock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ if (lock->active_threads) {
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE))
+ P_ERROR ("PRWLock::p_rwlock_writer_trylock: p_mutex_unlock() failed(1)");
+
+ return FALSE;
+ }
+
+ lock->active_threads = P_RWLOCK_SET_WRITERS (lock->active_threads, 1);
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_trylock: p_mutex_unlock() failed(2)");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_unlock (PRWLock *lock)
+{
+ pboolean signal_ok;
+
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (p_mutex_lock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_unlock: p_mutex_lock() failed");
+ return FALSE;
+ }
+
+ lock->active_threads = P_RWLOCK_SET_WRITERS (lock->active_threads, 0);
+
+ signal_ok = TRUE;
+
+ if (P_RWLOCK_WRITER_COUNT (lock->waiting_threads)) {
+ if (P_UNLIKELY (p_cond_variable_signal (lock->write_cv) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_unlock: p_cond_variable_signal() failed");
+ signal_ok = FALSE;
+ }
+ } else if (P_RWLOCK_READER_COUNT (lock->waiting_threads)) {
+ if (P_UNLIKELY (p_cond_variable_broadcast (lock->read_cv) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_unlock: p_cond_variable_broadcast() failed");
+ signal_ok = FALSE;
+ }
+ }
+
+ if (P_UNLIKELY (p_mutex_unlock (lock->mutex) == FALSE)) {
+ P_ERROR ("PRWLock::p_rwlock_writer_unlock: p_mutex_unlock() failed");
+ return FALSE;
+ }
+
+ return signal_ok;
+}
+
+P_LIB_API void
+p_rwlock_free (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return;
+
+ if (P_UNLIKELY (lock->active_threads))
+ P_WARNING ("PRWLock::p_rwlock_free: destroying while active threads are present");
+
+ if (P_UNLIKELY (lock->waiting_threads))
+ P_WARNING ("PRWLock::p_rwlock_free: destroying while waiting threads are present");
+
+ p_mutex_free (lock->mutex);
+ p_cond_variable_free (lock->read_cv);
+ p_cond_variable_free (lock->write_cv);
+
+ p_free (lock);
+}
+
+void
+p_rwlock_init (void)
+{
+}
+
+void
+p_rwlock_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/prwlock-none.c b/3rdparty/plibsys/src/prwlock-none.c
new file mode 100644
index 0000000..53fdb76
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock-none.c
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "prwlock.h"
+
+#include <stdlib.h>
+
+struct PRWLock_ {
+ pint hdl;
+};
+
+P_LIB_API PRWLock *
+p_rwlock_new (void)
+{
+ return NULL;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_lock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_trylock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_unlock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_lock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_trylock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_unlock (PRWLock *lock)
+{
+ P_UNUSED (lock);
+
+ return FALSE;
+}
+
+P_LIB_API void
+p_rwlock_free (PRWLock *lock)
+{
+ P_UNUSED (lock);
+}
+
+void
+p_rwlock_init (void)
+{
+}
+
+void
+p_rwlock_shutdown (void)
+{
+}
+
diff --git a/3rdparty/plibsys/src/prwlock-posix.c b/3rdparty/plibsys/src/prwlock-posix.c
new file mode 100644
index 0000000..817de8c
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock-posix.c
@@ -0,0 +1,151 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "prwlock.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+
+typedef pthread_rwlock_t rwlock_hdl;
+
+struct PRWLock_ {
+ rwlock_hdl hdl;
+};
+
+static pboolean pp_rwlock_unlock_any (PRWLock *lock);
+
+static pboolean
+pp_rwlock_unlock_any (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_LIKELY (pthread_rwlock_unlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::pp_rwlock_unlock_any: pthread_rwlock_unlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API PRWLock *
+p_rwlock_new (void)
+{
+ PRWLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PRWLock))) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pthread_rwlock_init (&ret->hdl, NULL) != 0)) {
+ P_ERROR ("PRWLock::p_rwlock_new: pthread_rwlock_init() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (pthread_rwlock_rdlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::p_rwlock_reader_lock: pthread_rwlock_rdlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return (pthread_rwlock_tryrdlock (&lock->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_unlock (PRWLock *lock)
+{
+ return pp_rwlock_unlock_any (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (pthread_rwlock_wrlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::p_rwlock_writer_lock: pthread_rwlock_wrlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return (pthread_rwlock_trywrlock (&lock->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_unlock (PRWLock *lock)
+{
+ return pp_rwlock_unlock_any (lock);
+}
+
+P_LIB_API void
+p_rwlock_free (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return;
+
+ if (P_UNLIKELY (pthread_rwlock_destroy (&lock->hdl) != 0))
+ P_ERROR ("PRWLock::p_rwlock_free: pthread_rwlock_destroy() failed");
+
+ p_free (lock);
+}
+
+void
+p_rwlock_init (void)
+{
+}
+
+void
+p_rwlock_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/prwlock-solaris.c b/3rdparty/plibsys/src/prwlock-solaris.c
new file mode 100644
index 0000000..c29d345
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock-solaris.c
@@ -0,0 +1,151 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "prwlock.h"
+
+#include <stdlib.h>
+#include <thread.h>
+
+typedef rwlock_t rwlock_hdl;
+
+struct PRWLock_ {
+ rwlock_hdl hdl;
+};
+
+static pboolean pp_rwlock_unlock_any (PRWLock *lock);
+
+static pboolean
+pp_rwlock_unlock_any (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_LIKELY (rw_unlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::pp_rwlock_unlock_any: rw_unlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API PRWLock *
+p_rwlock_new (void)
+{
+ PRWLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PRWLock))) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (rwlock_init (&ret->hdl, USYNC_THREAD, NULL) != 0)) {
+ P_ERROR ("PRWLock::p_rwlock_new: rwlock_init() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (rw_rdlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::p_rwlock_reader_lock: rw_rdlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return (rw_tryrdlock (&lock->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_unlock (PRWLock *lock)
+{
+ return pp_rwlock_unlock_any (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (rw_wrlock (&lock->hdl) == 0))
+ return TRUE;
+ else {
+ P_ERROR ("PRWLock::p_rwlock_writer_lock: rw_wrlock() failed");
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return (rw_trywrlock (&lock->hdl) == 0) ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_unlock (PRWLock *lock)
+{
+ return pp_rwlock_unlock_any (lock);
+}
+
+P_LIB_API void
+p_rwlock_free (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return;
+
+ if (P_UNLIKELY (rwlock_destroy (&lock->hdl) != 0))
+ P_ERROR ("PRWLock::p_rwlock_free: rwlock_destroy() failed");
+
+ p_free (lock);
+}
+
+void
+p_rwlock_init (void)
+{
+}
+
+void
+p_rwlock_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/prwlock-win.c b/3rdparty/plibsys/src/prwlock-win.c
new file mode 100644
index 0000000..3064223
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock-win.c
@@ -0,0 +1,548 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* More emulation variants: https://github.com/neosmart/RWLock */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "puthread.h"
+#include "prwlock.h"
+
+#include <stdlib.h>
+
+#define P_RWLOCK_XP_MAX_SPIN 4000
+#define P_RWLOCK_XP_IS_CLEAR(lock) (((lock) & 0x40007FFF) == 0)
+#define P_RWLOCK_XP_IS_WRITER(lock) (((lock) & 0x40000000) != 0)
+#define P_RWLOCK_XP_SET_WRITER(lock) ((lock) | 0x40000000)
+#define P_RWLOCK_XP_UNSET_WRITER(lock) ((lock) & (~0x40000000))
+#define P_RWLOCK_XP_SET_READERS(lock, readers) (((lock) & (~0x00007FFF)) | (readers))
+#define P_RWLOCK_XP_READER_COUNT(lock) ((lock) & 0x00007FFF)
+#define P_RWLOCK_XP_SET_WAITING(lock, waiting) (((lock) & (~0x3FFF8000)) | ((waiting) << 15))
+#define P_RWLOCK_XP_WAITING_COUNT(lock) (((lock) & 0x3FFF8000) >> 15)
+
+typedef VOID (WINAPI *InitializeSRWLockFunc) (ppointer lock);
+typedef VOID (WINAPI *AcquireSRWLockExclusiveFunc) (ppointer lock);
+typedef BOOLEAN (WINAPI *TryAcquireSRWLockExclusiveFunc) (ppointer lock);
+typedef VOID (WINAPI *ReleaseSRWLockExclusiveFunc) (ppointer lock);
+typedef VOID (WINAPI *AcquireSRWLockSharedFunc) (ppointer lock);
+typedef BOOLEAN (WINAPI *TryAcquireSRWLockSharedFunc) (ppointer lock);
+typedef VOID (WINAPI *ReleaseSRWLockSharedFunc) (ppointer lock);
+
+typedef pboolean (* PWin32LockInit) (PRWLock *lock);
+typedef void (* PWin32LockClose) (PRWLock *lock);
+typedef pboolean (* PWin32LockStartRead) (PRWLock *lock);
+typedef pboolean (* PWin32LockStartReadTry) (PRWLock *lock);
+typedef pboolean (* PWin32LockEndRead) (PRWLock *lock);
+typedef pboolean (* PWin32LockStartWrite) (PRWLock *lock);
+typedef pboolean (* PWin32LockStartWriteTry) (PRWLock *lock);
+typedef pboolean (* PWin32LockEndWrite) (PRWLock *lock);
+
+static PWin32LockInit pp_rwlock_init_func = NULL;
+static PWin32LockClose pp_rwlock_close_func = NULL;
+static PWin32LockStartRead pp_rwlock_start_read_func = NULL;
+static PWin32LockStartReadTry pp_rwlock_start_read_try_func = NULL;
+static PWin32LockEndRead pp_rwlock_end_read_func = NULL;
+static PWin32LockStartWrite pp_rwlock_start_write_func = NULL;
+static PWin32LockStartWriteTry pp_rwlock_start_write_try_func = NULL;
+static PWin32LockEndWrite pp_rwlock_end_write_func = NULL;
+
+typedef struct PRWLockVistaTable_ {
+ InitializeSRWLockFunc rwl_init;
+ AcquireSRWLockExclusiveFunc rwl_excl_lock;
+ TryAcquireSRWLockExclusiveFunc rwl_excl_lock_try;
+ ReleaseSRWLockExclusiveFunc rwl_excl_rel;
+ AcquireSRWLockSharedFunc rwl_shr_lock;
+ TryAcquireSRWLockSharedFunc rwl_shr_lock_try;
+ ReleaseSRWLockSharedFunc rwl_shr_rel;
+} PRWLockVistaTable;
+
+typedef struct PRWLockXP_ {
+ volatile puint32 lock;
+ HANDLE event;
+} PRWLockXP;
+
+struct PRWLock_ {
+ ppointer lock;
+};
+
+static PRWLockVistaTable pp_rwlock_vista_table = {NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL};
+
+/* SRWLock routines */
+static pboolean pp_rwlock_init_vista (PRWLock *lock);
+static void pp_rwlock_close_vista (PRWLock *lock);
+static pboolean pp_rwlock_start_read_vista (PRWLock *lock);
+static pboolean pp_rwlock_start_read_try_vista (PRWLock *lock);
+static pboolean pp_rwlock_end_read_vista (PRWLock *lock);
+static pboolean pp_rwlock_start_write_vista (PRWLock *lock);
+static pboolean pp_rwlock_start_write_try_vista (PRWLock *lock);
+static pboolean pp_rwlock_end_write_vista (PRWLock *lock);
+
+/* Windows XP emulation routines */
+static pboolean pp_rwlock_init_xp (PRWLock *lock);
+static void pp_rwlock_close_xp (PRWLock *lock);
+static pboolean pp_rwlock_start_read_xp (PRWLock *lock);
+static pboolean pp_rwlock_start_read_try_xp (PRWLock *lock);
+static pboolean pp_rwlock_end_read_xp (PRWLock *lock);
+static pboolean pp_rwlock_start_write_xp (PRWLock *lock);
+static pboolean pp_rwlock_start_write_try_xp (PRWLock *lock);
+static pboolean pp_rwlock_end_write_xp (PRWLock *lock);
+
+/* SRWLock routines */
+
+static pboolean
+pp_rwlock_init_vista (PRWLock *lock)
+{
+ pp_rwlock_vista_table.rwl_init (lock);
+
+ return TRUE;
+}
+
+static void
+pp_rwlock_close_vista (PRWLock *lock)
+{
+ P_UNUSED (lock);
+}
+
+static pboolean
+pp_rwlock_start_read_vista (PRWLock *lock)
+{
+ pp_rwlock_vista_table.rwl_shr_lock (lock);
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_read_try_vista (PRWLock *lock)
+{
+ return pp_rwlock_vista_table.rwl_shr_lock_try (lock) != 0 ? TRUE : FALSE;
+}
+
+static pboolean
+pp_rwlock_end_read_vista (PRWLock *lock)
+{
+ pp_rwlock_vista_table.rwl_shr_rel (lock);
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_write_vista (PRWLock *lock)
+{
+ pp_rwlock_vista_table.rwl_excl_lock (lock);
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_write_try_vista (PRWLock *lock)
+{
+ return pp_rwlock_vista_table.rwl_excl_lock_try (lock) != 0 ? TRUE : FALSE;
+}
+
+static pboolean
+pp_rwlock_end_write_vista (PRWLock *lock)
+{
+ pp_rwlock_vista_table.rwl_excl_rel (lock);
+
+ return TRUE;
+}
+
+/* Windows XP emulation routines */
+
+static pboolean
+pp_rwlock_init_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp;
+
+ if ((lock->lock = p_malloc0 (sizeof (PRWLockXP))) == NULL) {
+ P_ERROR ("PRWLock::pp_rwlock_init_xp: failed to allocate memory");
+ return FALSE;
+ }
+
+ rwl_xp = ((PRWLockXP *) lock->lock);
+
+ rwl_xp->lock = 0;
+ rwl_xp->event = CreateEventA (NULL, FALSE, FALSE, NULL);
+
+ if (P_UNLIKELY (rwl_xp->event == NULL)) {
+ P_ERROR ("PRWLock::pp_rwlock_init_xp: CreateEventA() failed");
+ p_free (lock->lock);
+ lock->lock = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_rwlock_close_xp (PRWLock *lock)
+{
+ CloseHandle (((PRWLockXP *) lock->lock)->event);
+ p_free (lock->lock);
+}
+
+static pboolean
+pp_rwlock_start_read_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ int i;
+ puint32 tmp_lock;
+ puint32 counter;
+
+ for (i = 0; ; ++i) {
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+
+ if (!P_RWLOCK_XP_IS_WRITER (tmp_lock)) {
+ counter = P_RWLOCK_XP_SET_READERS (tmp_lock, P_RWLOCK_XP_READER_COUNT (tmp_lock) + 1);
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) == TRUE)
+ return TRUE;
+ else
+ continue;
+ } else {
+ if (P_LIKELY (i < P_RWLOCK_XP_MAX_SPIN)) {
+ p_uthread_yield ();
+ continue;
+ }
+
+ counter = P_RWLOCK_XP_SET_WAITING (tmp_lock, P_RWLOCK_XP_WAITING_COUNT (tmp_lock) + 1);
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) != TRUE)
+ continue;
+
+ i = 0;
+
+ if (P_UNLIKELY (WaitForSingleObject (rwl_xp->event, INFINITE) != WAIT_OBJECT_0))
+ P_WARNING ("PRWLock::pp_rwlock_start_read_xp: WaitForSingleObject() failed, go ahead");
+
+ do {
+ tmp_lock = p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+ counter = P_RWLOCK_XP_SET_WAITING (tmp_lock, P_RWLOCK_XP_WAITING_COUNT (tmp_lock) - 1);
+ } while (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) != TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_read_try_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ puint32 tmp_lock;
+ puint32 counter;
+
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+
+ if (P_RWLOCK_XP_IS_WRITER (tmp_lock))
+ return FALSE;
+
+ counter = P_RWLOCK_XP_SET_READERS (tmp_lock, P_RWLOCK_XP_READER_COUNT (tmp_lock) + 1);
+
+ return p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter);
+}
+
+static pboolean
+pp_rwlock_end_read_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ puint32 tmp_lock;
+ puint32 counter;
+
+ while (TRUE) {
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+ counter = P_RWLOCK_XP_READER_COUNT (tmp_lock);
+
+ if (P_UNLIKELY (counter == 0))
+ return TRUE;
+
+ if (counter == 1 && P_RWLOCK_XP_WAITING_COUNT (tmp_lock) != 0) {
+ /* A duplicate wake up notification is possible */
+ if (P_UNLIKELY (SetEvent (rwl_xp->event) == 0))
+ P_WARNING ("PRWLock::pp_rwlock_end_read_xp: SetEvent() failed");
+ }
+
+ counter = P_RWLOCK_XP_SET_READERS (tmp_lock, counter - 1);
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) == TRUE)
+ break;
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_write_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ int i;
+ puint32 tmp_lock;
+ puint32 counter;
+
+ for (i = 0; ; ++i) {
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+
+ if (P_RWLOCK_XP_IS_CLEAR (tmp_lock)) {
+ counter = P_RWLOCK_XP_SET_WRITER (tmp_lock);
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) == TRUE)
+ return TRUE;
+ else
+ continue;
+ } else {
+ if (P_LIKELY (i < P_RWLOCK_XP_MAX_SPIN)) {
+ p_uthread_yield ();
+ continue;
+ }
+
+ counter = P_RWLOCK_XP_SET_WAITING (tmp_lock, P_RWLOCK_XP_WAITING_COUNT (tmp_lock) + 1);
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) != TRUE)
+ continue;
+
+ i = 0;
+
+ if (P_UNLIKELY (WaitForSingleObject (rwl_xp->event, INFINITE) != WAIT_OBJECT_0))
+ P_WARNING ("PRWLock::pp_rwlock_start_write_xp: WaitForSingleObject() failed, go ahead");
+
+ do {
+ tmp_lock = p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+ counter = P_RWLOCK_XP_SET_WAITING (tmp_lock, P_RWLOCK_XP_WAITING_COUNT (tmp_lock) - 1);
+ } while (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) counter) != TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_rwlock_start_write_try_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ puint32 tmp_lock;
+
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+
+ if (P_RWLOCK_XP_IS_CLEAR (tmp_lock)) {
+ return p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) P_RWLOCK_XP_SET_WRITER (tmp_lock));
+ }
+
+ return FALSE;
+}
+
+static pboolean
+pp_rwlock_end_write_xp (PRWLock *lock)
+{
+ PRWLockXP *rwl_xp = ((PRWLockXP *) lock->lock);
+ puint32 tmp_lock;
+
+ while (TRUE) {
+ while (TRUE) {
+ tmp_lock = (puint32) p_atomic_int_get ((const volatile pint *) &rwl_xp->lock);
+
+ if (P_UNLIKELY (!P_RWLOCK_XP_IS_WRITER (tmp_lock)))
+ return TRUE;
+
+ if (P_RWLOCK_XP_WAITING_COUNT (tmp_lock) == 0)
+ break;
+
+ /* Only the one end-of-write call can be */
+ if (P_UNLIKELY (SetEvent (rwl_xp->event) == 0))
+ P_WARNING ("PRWLock::pp_rwlock_end_write_xp: SetEvent() failed");
+ }
+
+ if (p_atomic_int_compare_and_exchange ((volatile pint *) &rwl_xp->lock,
+ (pint) tmp_lock,
+ (pint) P_RWLOCK_XP_UNSET_WRITER (tmp_lock)) == TRUE)
+ break;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API PRWLock *
+p_rwlock_new (void)
+{
+ PRWLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PRWLock))) == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pp_rwlock_init_func (ret) != TRUE)) {
+ P_ERROR ("PRWLock::p_rwlock_new: failed to initialize");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_start_read_func (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_start_read_try_func (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_reader_unlock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_end_read_func (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_lock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_start_write_func (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_trylock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_start_write_try_func (lock);
+}
+
+P_LIB_API pboolean
+p_rwlock_writer_unlock (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return FALSE;
+
+ return pp_rwlock_end_write_func (lock);
+}
+
+P_LIB_API void
+p_rwlock_free (PRWLock *lock)
+{
+ if (P_UNLIKELY (lock == NULL))
+ return;
+
+ pp_rwlock_close_func (lock);
+ p_free (lock);
+}
+
+void
+p_rwlock_init (void)
+{
+ HMODULE hmodule;
+
+ hmodule = GetModuleHandleA ("kernel32.dll");
+
+ if (P_UNLIKELY (hmodule == NULL)) {
+ P_ERROR ("PRWLock::p_rwlock_init: failed to load kernel32.dll module");
+ return;
+ }
+
+ pp_rwlock_vista_table.rwl_init = (InitializeSRWLockFunc) GetProcAddress (hmodule,
+ "InitializeSRWLock");
+
+ if (P_LIKELY (pp_rwlock_vista_table.rwl_init != NULL)) {
+ pp_rwlock_vista_table.rwl_excl_lock = (AcquireSRWLockExclusiveFunc) GetProcAddress (hmodule,
+ "AcquireSRWLockExclusive");
+ pp_rwlock_vista_table.rwl_excl_lock_try = (TryAcquireSRWLockExclusiveFunc) GetProcAddress (hmodule,
+ "TryAcquireSRWLockExclusive");
+ pp_rwlock_vista_table.rwl_excl_rel = (ReleaseSRWLockExclusiveFunc) GetProcAddress (hmodule,
+ "ReleaseSRWLockExclusive");
+ pp_rwlock_vista_table.rwl_shr_lock = (AcquireSRWLockSharedFunc) GetProcAddress (hmodule,
+ "AcquireSRWLockShared");
+ pp_rwlock_vista_table.rwl_shr_lock_try = (TryAcquireSRWLockSharedFunc) GetProcAddress (hmodule,
+ "TryAcquireSRWLockShared");
+ pp_rwlock_vista_table.rwl_shr_rel = (ReleaseSRWLockSharedFunc) GetProcAddress (hmodule,
+ "ReleaseSRWLockShared");
+ pp_rwlock_init_func = pp_rwlock_init_vista;
+ pp_rwlock_close_func = pp_rwlock_close_vista;
+ pp_rwlock_start_read_func = pp_rwlock_start_read_vista;
+ pp_rwlock_start_read_try_func = pp_rwlock_start_read_try_vista;
+ pp_rwlock_end_read_func = pp_rwlock_end_read_vista;
+ pp_rwlock_start_write_func = pp_rwlock_start_write_vista;
+ pp_rwlock_start_write_try_func = pp_rwlock_start_write_try_vista;
+ pp_rwlock_end_write_func = pp_rwlock_end_write_vista;
+ } else {
+ pp_rwlock_init_func = pp_rwlock_init_xp;
+ pp_rwlock_close_func = pp_rwlock_close_xp;
+ pp_rwlock_start_read_func = pp_rwlock_start_read_xp;
+ pp_rwlock_start_read_try_func = pp_rwlock_start_read_try_xp;
+ pp_rwlock_end_read_func = pp_rwlock_end_read_xp;
+ pp_rwlock_start_write_func = pp_rwlock_start_write_xp;
+ pp_rwlock_start_write_try_func = pp_rwlock_start_write_try_xp;
+ pp_rwlock_end_write_func = pp_rwlock_end_write_xp;
+ }
+}
+
+void
+p_rwlock_shutdown (void)
+{
+ memset (&pp_rwlock_vista_table, 0, sizeof (pp_rwlock_vista_table));
+
+ pp_rwlock_init_func = NULL;
+ pp_rwlock_close_func = NULL;
+ pp_rwlock_start_read_func = NULL;
+ pp_rwlock_start_read_try_func = NULL;
+ pp_rwlock_end_read_func = NULL;
+ pp_rwlock_start_write_func = NULL;
+ pp_rwlock_start_write_try_func = NULL;
+ pp_rwlock_end_write_func = NULL;
+}
diff --git a/3rdparty/plibsys/src/prwlock.h b/3rdparty/plibsys/src/prwlock.h
new file mode 100644
index 0000000..9f61e4a
--- /dev/null
+++ b/3rdparty/plibsys/src/prwlock.h
@@ -0,0 +1,185 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file prwlock.h
+ * @brief Read-write lock
+ * @author Alexander Saprykin
+ *
+ * A read-write lock is a synchronization primitive which allows access to a
+ * critical section to not only the one thread, but instead it splits all
+ * threads into the two groups:
+ * - reader threads which perform only the reading operations without any shared
+ * data modifications;
+ * - writer threads which may perform the shared data modifitcations as well as
+ * its reading.
+ *
+ * When there are only the reader threads inside a critical section it is called
+ * a shared lock - actually you do not need any locking mechanism and all the
+ * threads share the lock. In this situation an arbitrary number of reader
+ * threads can perform shared data reading.
+ *
+ * The situation changes when a writer thread requests access to the same
+ * critical section. It will wait until all the current readers finish
+ * executing the critical section before acquiring the lock in exclusive manner:
+ * no one else can access the critical section until the writer finishes with
+ * it. Even another writer thread will have to wait for the lock to be released
+ * by the first writer before entering the critical section.
+ *
+ * To prevent writer startvation usually writers are in favor over readers,
+ * which is actually implementation dependent, though most operating systems try
+ * to follow this rule.
+ *
+ * A read-write lock is usually used when the writing operations are not
+ * performed too frequently, or when the number of reader threads is a way more
+ * than writer ones.
+ *
+ * A reader enters a critical section with p_rwlock_reader_lock() or
+ * p_rwlock_reader_trylock() and exits with p_rwlock_reader_unlock().
+ *
+ * A writer enters the critical section with p_rwlock_writer_lock() or
+ * p_rwlock_writer_trylock() and exits with p_rwlock_writer_unlock().
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PRWLOCK_H
+#define PLIBSYS_HEADER_PRWLOCK_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Read-write lock opaque data structure. */
+typedef struct PRWLock_ PRWLock;
+
+/**
+ * @brief Creates a new #PRWLock object.
+ * @return Pointer to a newly created #PRWLock object.
+ * @since 0.0.1
+ */
+P_LIB_API PRWLock * p_rwlock_new (void);
+
+/**
+ * @brief Locks a read-write lock for reading.
+ * @param lock #PRWLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock a read-write lock recursively - it may lead to an
+ * application deadlock (implementation dependent).
+ *
+ * Forces the calling thread to sleep until the @a lock becomes available for
+ * locking.
+ */
+P_LIB_API pboolean p_rwlock_reader_lock (PRWLock *lock);
+
+/**
+ * @brief Tries to lock a read-write lock for reading immediately.
+ * @param lock #PRWLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock a read-write lock recursively - it may lead to an
+ * application deadlock (implementation dependent).
+ *
+ * Tries to lock the @a lock and returns immediately if it is not available for
+ * locking.
+ */
+P_LIB_API pboolean p_rwlock_reader_trylock (PRWLock *lock);
+
+/**
+ * @brief Releases a locked for reading read-write lock.
+ * @param lock #PRWLock to release.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not use this function on non-locked read-write locks - behavior
+ * may be unpredictable.
+ * @warning Do not use this function to unlock a read-write lock which was
+ * locked for writing.
+ *
+ * If the @a lock was previously locked for reading then it becomes unlocked.
+ *
+ * It's implementation dependent whether only the same thread can lock and
+ * unlock the same read-write lock.
+ */
+P_LIB_API pboolean p_rwlock_reader_unlock (PRWLock *lock);
+
+/**
+ * @brief Locks a read-write lock for writing.
+ * @param lock #PRWLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock a read-write lock recursively - it may lead to an
+ * application deadlock (implementation dependent).
+ *
+ * Forces the calling thread to sleep until the @a lock becomes available for
+ * locking.
+ */
+P_LIB_API pboolean p_rwlock_writer_lock (PRWLock *lock);
+
+/**
+ * @brief Tries to lock a read-write lock immediately.
+ * @param lock #PRWLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not lock a read-write lock recursively - it may lead to an
+ * application deadlock (implementation dependent).
+ *
+ * Tries to lock the @a lock and returns immediately if it is not available for
+ * locking.
+ */
+P_LIB_API pboolean p_rwlock_writer_trylock (PRWLock *lock);
+
+/**
+ * @brief Releases a locked for writing read-write lock.
+ * @param lock #PRWLock to release.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Do not use this function on non-locked read-write locks - behavior
+ * may be unpredictable.
+ * @warning Do not use this function to unlock a read-write lock which was
+ * locked for reading.
+ *
+ * If the @a lock was previously locked for writing then it becomes unlocked.
+ *
+ * It's implementation dependent whether only the same thread can lock and
+ * unlock the same read-write lock.
+ */
+P_LIB_API pboolean p_rwlock_writer_unlock (PRWLock *lock);
+
+/**
+ * @brief Frees a #PRWLock object.
+ * @param lock #PRWLock to free.
+ * @since 0.0.1
+ * @warning It doesn't unlock the @a lock before freeing memory, so you should
+ * do it manually.
+ */
+P_LIB_API void p_rwlock_free (PRWLock *lock);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PRWLOCK_H */
diff --git a/3rdparty/plibsys/src/psemaphore-amiga.c b/3rdparty/plibsys/src/psemaphore-amiga.c
new file mode 100644
index 0000000..bff0acf
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-amiga.c
@@ -0,0 +1,250 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <exec/types.h>
+#include <exec/semaphores.h>
+#include <proto/exec.h>
+
+#define P_SEM_SUFFIX "_p_sem_object"
+#define P_SEM_PRIV_SIZE (sizeof (psize))
+
+struct PSemaphore_ {
+ struct SignalSemaphore *sem_shared;
+ pchar *platform_key;
+ pboolean is_owner;
+ PSemaphoreAccessMode mode;
+};
+
+static pboolean pp_semaphore_create_handle (PSemaphore *sem, PError **error);
+
+static pboolean
+pp_semaphore_create_handle (PSemaphore *sem,
+ PError **error)
+{
+ struct SignalSemaphore *sem_sys;
+ psize name_len;
+ pchar *name;
+
+ if (P_UNLIKELY (sem == NULL || sem->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ IExec->Forbid ();
+
+ sem_sys = (struct SignalSemaphore *) IExec->FindSemaphore (sem->platform_key);
+
+ if (sem_sys != NULL && sem->mode != P_SEM_ACCESS_CREATE) {
+ sem->sem_shared = sem_sys;
+ } else {
+ if (sem_sys != NULL && sem->mode == P_SEM_ACCESS_CREATE) {
+ IExec->RemSemaphore (sem_sys);
+ IExec->ObtainSemaphore (sem_sys);
+ IExec->ReleaseSemaphore (sem_sys);
+
+ IExec->FreeVec (sem_sys->ss_Link.ln_Name);
+ IExec->FreeVec (((psize *) sem_sys) - 1);
+ }
+
+ sem_sys = (struct SignalSemaphore *) IExec->AllocVecTags (sizeof (struct SignalSemaphore) + P_SEM_PRIV_SIZE,
+ AVT_Type, MEMF_SHARED,
+ AVT_ClearWithValue, 0,
+ TAG_END);
+
+ if (P_UNLIKELY (sem_sys == NULL)) {
+ IExec->Permit ();
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to call AllocMem() to create semaphore");
+ return FALSE;
+ }
+
+ name_len = strlen (sem->platform_key);
+ name = (pchar *) IExec->AllocVecTags (name_len + 1,
+ AVT_ClearWithValue, 0,
+ TAG_END);
+
+ if (P_UNLIKELY (name == NULL)) {
+ IExec->FreeVec (sem_sys);
+ IExec->Permit ();
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to call AllocMem() to create semaphore name");
+ return FALSE;
+ }
+
+ memcpy (name, sem->platform_key, name_len);
+
+ /* Leave space in memory for counter */
+ sem_sys = (struct SignalSemaphore *) (((psize *) sem_sys) + 1);
+
+ sem_sys->ss_Link.ln_Name = name;
+ sem->sem_shared = sem_sys;
+
+ /* Add to system list */
+ IExec->AddSemaphore (sem_sys);
+ }
+
+ *(((psize *) sem_sys) - 1) += 1;
+
+ IExec->Permit ();
+
+ return TRUE;
+}
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ PSemaphore *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL || init_val < 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSemaphore))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SEM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ p_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SEM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->mode = mode;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (ret, error) == FALSE)) {
+ p_semaphore_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ sem->is_owner = TRUE;
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ IExec->ObtainSemaphore (sem->sem_shared);
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ IExec->ReleaseSemaphore (sem->sem_shared);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ if (P_UNLIKELY (sem->sem_shared != NULL)) {
+ IExec->Forbid ();
+
+ *(((psize *) sem->sem_shared) - 1) -= 1;
+
+ if (*(((psize *) sem->sem_shared) - 1) == 0 || sem->is_owner == TRUE) {
+ IExec->RemSemaphore (sem->sem_shared);
+ IExec->ObtainSemaphore (sem->sem_shared);
+ IExec->ReleaseSemaphore (sem->sem_shared);
+
+ IExec->FreeVec (sem->sem_shared->ss_Link.ln_Name);
+ IExec->FreeVec (((psize *) sem->sem_shared) - 1);
+ }
+
+ IExec->Permit ();
+ }
+
+ if (P_LIKELY (sem->platform_key != NULL))
+ p_free (sem->platform_key);
+
+ p_free (sem);
+}
diff --git a/3rdparty/plibsys/src/psemaphore-none.c b/3rdparty/plibsys/src/psemaphore-none.c
new file mode 100644
index 0000000..8744123
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-none.c
@@ -0,0 +1,91 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "psemaphore.h"
+
+#include <stdlib.h>
+
+struct PSemaphore_ {
+ pint hdl;
+};
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ P_UNUSED (name);
+ P_UNUSED (init_val);
+ P_UNUSED (mode);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return NULL;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ P_UNUSED (sem);
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ P_UNUSED (sem);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ P_UNUSED (sem);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return FALSE;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ P_UNUSED (sem);
+}
+
diff --git a/3rdparty/plibsys/src/psemaphore-os2.c b/3rdparty/plibsys/src/psemaphore-os2.c
new file mode 100644
index 0000000..72cc7d3
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-os2.c
@@ -0,0 +1,91 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "psemaphore.h"
+
+#include <stdlib.h>
+
+struct PSemaphore_ {
+ pint hdl;
+};
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ P_UNUSED (name);
+ P_UNUSED (init_val);
+ P_UNUSED (mode);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return NULL;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ P_UNUSED (sem);
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ P_UNUSED (sem);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ P_UNUSED (sem);
+
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NOT_IMPLEMENTED,
+ 0,
+ "No semaphore implementation");
+
+ return FALSE;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ P_UNUSED (sem);
+}
+
diff --git a/3rdparty/plibsys/src/psemaphore-posix.c b/3rdparty/plibsys/src/psemaphore-posix.c
new file mode 100644
index 0000000..f98a045
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-posix.c
@@ -0,0 +1,272 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#define P_SEM_SUFFIX "_p_sem_object"
+
+typedef sem_t psem_hdl;
+
+/* On some HP-UX versions it may not be defined */
+#ifndef SEM_FAILED
+# define SEM_FAILED ((sem_t *) -1)
+#endif
+
+#ifdef P_OS_SOLARIS
+# define P_SEM_INVALID_HDL (sem_t *) -1
+#else
+# define P_SEM_INVALID_HDL SEM_FAILED
+#endif
+
+struct PSemaphore_ {
+ pboolean sem_created;
+ pchar *platform_key;
+#if defined (P_OS_VMS) && (PLIBSYS_SIZEOF_VOID_P == 4)
+# pragma __pointer_size 64
+#endif
+ psem_hdl *sem_hdl;
+#if defined (P_OS_VMS) && (PLIBSYS_SIZEOF_VOID_P == 4)
+# pragma __pointer_size 32
+#endif
+ PSemaphoreAccessMode mode;
+ pint init_val;
+};
+
+static pboolean pp_semaphore_create_handle (PSemaphore *sem, PError **error);
+static void pp_semaphore_clean_handle (PSemaphore *sem);
+
+static pboolean
+pp_semaphore_create_handle (PSemaphore *sem,
+ PError **error)
+{
+ pint init_val;
+
+ if (P_UNLIKELY (sem == NULL || sem->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ init_val = sem->init_val;
+
+ /* Solaris may interrupt sem_open() call */
+ while ((sem->sem_hdl = sem_open (sem->platform_key,
+ O_CREAT | O_EXCL,
+ 0660,
+ init_val)) == P_SEM_INVALID_HDL &&
+ p_error_get_last_system () == EINTR)
+ ;
+
+ if (sem->sem_hdl == P_SEM_INVALID_HDL) {
+ if (p_error_get_last_system () == EEXIST) {
+ if (sem->mode == P_SEM_ACCESS_CREATE)
+ sem_unlink (sem->platform_key);
+ else
+ init_val = 0;
+
+ while ((sem->sem_hdl = sem_open (sem->platform_key,
+ 0,
+ 0,
+ init_val)) == P_SEM_INVALID_HDL &&
+ p_error_get_last_system () == EINTR)
+ ;
+ }
+ } else
+ sem->sem_created = TRUE;
+
+ if (P_UNLIKELY (sem->sem_hdl == P_SEM_INVALID_HDL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call sem_open() to create semaphore");
+ pp_semaphore_clean_handle (sem);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_semaphore_clean_handle (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem->sem_hdl != P_SEM_INVALID_HDL &&
+ sem_close (sem->sem_hdl) == -1))
+ P_ERROR ("PSemaphore::pp_semaphore_clean_handle: sem_close() failed");
+
+ if (sem->sem_hdl != P_SEM_INVALID_HDL &&
+ sem->sem_created == TRUE &&
+ sem_unlink (sem->platform_key) == -1)
+ P_ERROR ("PSemaphore::pp_semaphore_clean_handle: sem_unlink() failed");
+
+ sem->sem_created = FALSE;
+ sem->sem_hdl = P_SEM_INVALID_HDL;
+}
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ PSemaphore *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL || init_val < 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSemaphore))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SEM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ p_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SEM_SUFFIX);
+
+#if defined (P_OS_IRIX) || defined (P_OS_TRU64)
+ /* IRIX and Tru64 prefer filename styled IPC names */
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+#else
+ ret->platform_key = p_ipc_get_platform_key (new_name, TRUE);
+#endif
+ ret->init_val = init_val;
+ ret->mode = mode;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (ret, error) == FALSE)) {
+ p_semaphore_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ sem->sem_created = TRUE;
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+ pint res;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ while ((res = sem_wait (sem->sem_hdl)) == -1 && p_error_get_last_system () == EINTR)
+ ;
+
+ ret = (res == 0);
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call sem_wait() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ ret = (sem_post (sem->sem_hdl) == 0);
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call sem_post() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ pp_semaphore_clean_handle (sem);
+
+ if (P_LIKELY (sem->platform_key != NULL))
+ p_free (sem->platform_key);
+
+ p_free (sem);
+}
diff --git a/3rdparty/plibsys/src/psemaphore-sysv.c b/3rdparty/plibsys/src/psemaphore-sysv.c
new file mode 100644
index 0000000..34b33fc
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-sysv.c
@@ -0,0 +1,319 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+
+#define P_SEM_SUFFIX "_p_sem_object"
+#define P_SEM_INVALID_HDL -1
+
+struct sembuf sem_lock = {0, -1, SEM_UNDO};
+struct sembuf sem_unlock = {0, 1, SEM_UNDO};
+
+typedef union p_semun_ {
+ pint val;
+ struct semid_ds *buf;
+ pushort *array;
+} p_semun;
+
+typedef int psem_hdl;
+
+struct PSemaphore_ {
+ pboolean file_created;
+ pboolean sem_created;
+ key_t unix_key;
+ pchar *platform_key;
+ psem_hdl sem_hdl;
+ PSemaphoreAccessMode mode;
+ pint init_val;
+};
+
+static pboolean pp_semaphore_create_handle (PSemaphore *sem, PError **error);
+static void pp_semaphore_clean_handle (PSemaphore *sem);
+
+static pboolean
+pp_semaphore_create_handle (PSemaphore *sem, PError **error)
+{
+ pint built;
+ p_semun semun_op;
+
+ if (P_UNLIKELY (sem == NULL || sem->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((built = p_ipc_unix_create_key_file (sem->platform_key)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to create key file");
+ pp_semaphore_clean_handle (sem);
+ return FALSE;
+ } else if (built == 0)
+ sem->file_created = TRUE;
+
+ if (P_UNLIKELY ((sem->unix_key = p_ipc_unix_get_ftok_key (sem->platform_key)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to get unique IPC key");
+ pp_semaphore_clean_handle (sem);
+ return FALSE;
+ }
+
+ if ((sem->sem_hdl = semget (sem->unix_key,
+ 1,
+ IPC_CREAT | IPC_EXCL | 0660)) == P_SEM_INVALID_HDL) {
+ if (p_error_get_last_system () == EEXIST)
+ sem->sem_hdl = semget (sem->unix_key, 1, 0660);
+ } else {
+ sem->sem_created = TRUE;
+
+ /* Maybe key file left after the crash, so take it */
+ sem->file_created = (built == 1);
+ }
+
+ if (P_UNLIKELY (sem->sem_hdl == P_SEM_INVALID_HDL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call semget() to create semaphore");
+ pp_semaphore_clean_handle (sem);
+ return FALSE;
+ }
+
+ if (sem->sem_created == TRUE || sem->mode == P_SEM_ACCESS_CREATE) {
+ semun_op.val = sem->init_val;
+
+ if (P_UNLIKELY (semctl (sem->sem_hdl, 0, SETVAL, semun_op) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to set semaphore initial value with semctl()");
+ pp_semaphore_clean_handle (sem);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+pp_semaphore_clean_handle (PSemaphore *sem)
+{
+ if (sem->sem_hdl != P_SEM_INVALID_HDL &&
+ sem->sem_created == TRUE &&
+ semctl (sem->sem_hdl, 0, IPC_RMID) == -1)
+ P_ERROR ("PSemaphore::pp_semaphore_clean_handle: semctl() with IPC_RMID failed");
+
+ if (sem->file_created == TRUE &&
+ sem->platform_key != NULL &&
+ unlink (sem->platform_key) == -1)
+ P_ERROR ("PSemaphore::pp_semaphore_clean_handle: unlink() failed");
+
+ sem->file_created = FALSE;
+ sem->sem_created = FALSE;
+ sem->unix_key = -1;
+ sem->sem_hdl = P_SEM_INVALID_HDL;
+}
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ PSemaphore *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL || init_val < 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSemaphore))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SEM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ p_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SEM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->init_val = init_val;
+ ret->mode = mode;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (ret, error) == FALSE)) {
+ p_semaphore_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ sem->sem_created = TRUE;
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+ pint res;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ while ((res = semop (sem->sem_hdl, &sem_lock, 1)) == -1 &&
+ p_error_get_last_system () == EINTR)
+ ;
+
+ ret = (res == 0);
+
+ if (P_UNLIKELY (ret == FALSE &&
+ (p_error_get_last_system () == EIDRM ||
+ p_error_get_last_system () == EINVAL))) {
+ P_WARNING ("PSemaphore::p_semaphore_acquire: trying to recreate");
+ pp_semaphore_clean_handle (sem);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (sem, error) == FALSE))
+ return FALSE;
+
+ while ((res = semop (sem->sem_hdl, &sem_lock, 1)) == -1 &&
+ p_error_get_last_system () == EINTR)
+ ;
+
+ ret = (res == 0);
+ }
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call semop() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+ pint res;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ while ((res = semop (sem->sem_hdl, &sem_unlock, 1)) == -1 &&
+ p_error_get_last_system () == EINTR)
+ ;
+
+ ret = (res == 0);
+
+ if (P_UNLIKELY (ret == FALSE &&
+ (p_error_get_last_system () == EIDRM ||
+ p_error_get_last_system () == EINVAL))) {
+ P_WARNING ("PSemaphore::p_semaphore_release: trying to recreate");
+ pp_semaphore_clean_handle (sem);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (sem, error) == FALSE))
+ return FALSE;
+
+ return TRUE;
+ }
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call semop() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ pp_semaphore_clean_handle (sem);
+
+ if (P_LIKELY (sem->platform_key != NULL))
+ p_free (sem->platform_key);
+
+ p_free (sem);
+}
diff --git a/3rdparty/plibsys/src/psemaphore-win.c b/3rdparty/plibsys/src/psemaphore-win.c
new file mode 100644
index 0000000..228c054
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore-win.c
@@ -0,0 +1,204 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define P_SEM_SUFFIX "_p_sem_object"
+#define P_SEM_INVALID_HDL NULL
+
+typedef HANDLE psem_hdl;
+
+struct PSemaphore_ {
+ pchar *platform_key;
+ psem_hdl sem_hdl;
+ pint init_val;
+};
+
+static pboolean pp_semaphore_create_handle (PSemaphore *sem, PError **error);
+static void pp_semaphore_clean_handle (PSemaphore *sem);
+
+static pboolean
+pp_semaphore_create_handle (PSemaphore *sem, PError **error)
+{
+ if (P_UNLIKELY (sem == NULL || sem->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ /* Multibyte character set must be enabled */
+ if (P_UNLIKELY ((sem->sem_hdl = CreateSemaphoreA (NULL,
+ sem->init_val,
+ MAXLONG,
+ sem->platform_key)) == P_SEM_INVALID_HDL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call CreateSemaphore() to create semaphore");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_semaphore_clean_handle (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem->sem_hdl != P_SEM_INVALID_HDL && CloseHandle (sem->sem_hdl) == 0))
+ P_ERROR ("PSemaphore::pp_semaphore_clean_handle: CloseHandle() failed");
+
+ sem->sem_hdl = P_SEM_INVALID_HDL;
+}
+
+P_LIB_API PSemaphore *
+p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error)
+{
+ PSemaphore *ret;
+ pchar *new_name;
+
+ P_UNUSED (mode);
+
+ if (P_UNLIKELY (name == NULL || init_val < 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSemaphore))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SEM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for semaphore");
+ p_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcpy (new_name, P_SEM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->init_val = init_val;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_semaphore_create_handle (ret, error) == FALSE)) {
+ p_semaphore_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_take_ownership (PSemaphore *sem)
+{
+ P_UNUSED (sem);
+}
+
+P_LIB_API pboolean
+p_semaphore_acquire (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ ret = (WaitForSingleObject (sem->sem_hdl, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call WaitForSingleObject() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_semaphore_release (PSemaphore *sem,
+ PError **error)
+{
+ pboolean ret;
+
+ if (P_UNLIKELY (sem == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ ret = ReleaseSemaphore (sem->sem_hdl, 1, NULL) ? TRUE : FALSE;
+
+ if (P_UNLIKELY (ret == FALSE))
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call ReleaseSemaphore() on semaphore");
+
+ return ret;
+}
+
+P_LIB_API void
+p_semaphore_free (PSemaphore *sem)
+{
+ if (P_UNLIKELY (sem == NULL))
+ return;
+
+ pp_semaphore_clean_handle (sem);
+
+ if (P_LIKELY (sem->platform_key != NULL))
+ p_free (sem->platform_key);
+
+ p_free (sem);
+}
diff --git a/3rdparty/plibsys/src/psemaphore.h b/3rdparty/plibsys/src/psemaphore.h
new file mode 100644
index 0000000..29fb48e
--- /dev/null
+++ b/3rdparty/plibsys/src/psemaphore.h
@@ -0,0 +1,191 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file psemaphore.h
+ * @brief Semaphore routines
+ * @author Alexander Saprykin
+ *
+ * A semaphore is a synchronization primitive which controls access to shared
+ * data from the concurrently running threads. Unlike a mutex (which is a
+ * particular case of a binary semaphore) it allows concurrent access not to
+ * only the one thread.
+ *
+ * The semaphore has a counter which means the number of available resources
+ * (units). Before entering a critical section a thread must perform the so
+ * called P (acquire) operation: if the counter is positive it decrements the
+ * counter by 1 and continues execution; otherwise the thread is suspended until
+ * the counter becomes positive. Before leaving the critical section the thread
+ * must perform the so called V (release) operation: increments the counter by 1
+ * and wakes up a waiting thread from the queue (if any).
+ *
+ * You can think about the semaphore as a resource controller: the P operation
+ * takes one unit, while the V operation gives one unit back. The thread could
+ * not continue execution without taking a resource unit. By setting the initial
+ * semaphore counter value you can control how much concurrent threads can work
+ * with a shared resource.
+ *
+ * This semaphore implementation is process-wide so you can synchronize not only
+ * the threads. But it makes this IPC primitive (actually like any other IPC
+ * primitive, as well) relatively heavy. Consider using a mutex or a spinlock
+ * instead if you do not need to cross a process boundary.
+ *
+ * A process-wide semaphore is identified by its name across the system, thus it
+ * is also called a named semaphore. Use p_semaphore_new() to open the named
+ * semaphore and p_semaphore_free() to close it.
+ *
+ * Please note the following platform specific differences:
+ *
+ * - Windows doesn't own IPC objects (processes own them), which means that a
+ * semaphore will be removed from the system after the last process or thread
+ * closes it (or after terminating all the processes and threads holding open
+ * semaphore).
+ *
+ * - UNIX systems own IPC objects. Because of that UNIX IPC objects can survive
+ * an application crash: an already used semaphore can be opened in a locked
+ * state and an application can fail into a deadlock or an inconsistent state.
+ * This could happen if you have not closed all the open semaphores explicitly
+ * before terminating the application.
+ *
+ * - IRIX allows to open several instances of a semaphore within the single
+ * process, but it will close the object after the first close call from any of
+ * the threads within the process.
+ *
+ * - AmigaOS has process-wide semaphores without actual tracking of counter,
+ * which means that semaphore behaves the same way as recursive mutex.
+ *
+ * - OpenVMS (as of 8.4 release) has declared prototypes for process-wide named
+ * semaphores but the actual implementation is broken.
+ *
+ * - OS/2 lacks support for process-wide named semaphores.
+ *
+ * - Syllable lacks support for process-wide named semaphores.
+ *
+ * - BeOS lacks support for process-wide named semaphores.
+ *
+ * Use the third argument as #P_SEM_ACCESS_CREATE in p_semaphore_new() to reset
+ * a semaphore value while opening it. This argument is ignored on Windows. You
+ * can also take ownership of the semaphore with p_semaphore_take_ownership() to
+ * explicitly remove it from the system after closing.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSEMAPHORE_H
+#define PLIBSYS_HEADER_PSEMAPHORE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Enum with semaphore creation modes. */
+typedef enum PSemaphoreAccessMode_ {
+ P_SEM_ACCESS_OPEN = 0, /**< Opens an existing semaphore or creates one with a given value. */
+ P_SEM_ACCESS_CREATE = 1 /**< Creates semaphore, resets to a given value if exists. */
+} PSemaphoreAccessMode;
+
+/** Semaphore opaque data structure. */
+typedef struct PSemaphore_ PSemaphore;
+
+/**
+ * @brief Creates a new #PSemaphore object.
+ * @param name Semaphore name.
+ * @param init_val Initial semaphore value.
+ * @param mode Creation mode.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to a newly created #PSemaphore object in case of success,
+ * NULL otherwise.
+ * @since 0.0.1
+ *
+ * The @a init_val is used only in one of following cases: a semaphore with the
+ * such name doesn't exist, or the semaphore with the such name exists but
+ * @a mode specified as #P_SEM_ACCESS_CREATE (non-Windows platforms only). In
+ * other cases @a init_val is ignored. The @a name is system-wide, so any other
+ * process can open that semaphore passing the same name.
+ */
+P_LIB_API PSemaphore * p_semaphore_new (const pchar *name,
+ pint init_val,
+ PSemaphoreAccessMode mode,
+ PError **error);
+
+/**
+ * @brief Takes ownership of a semaphore.
+ * @param sem Semaphore to take ownership.
+ * @since 0.0.1
+ *
+ * If you take ownership of a semaphore object, p_semaphore_free() will try to
+ * completely unlink it and remove from the system. This is useful on UNIX
+ * systems where the semaphore can survive an application crash. On the Windows
+ * platform this call has no effect.
+ *
+ * The common usage of this call is upon application startup to ensure that the
+ * semaphore from the previous crash will be unlinked from the system. To do
+ * that, call p_semaphore_new(), take ownership of the semaphore object and
+ * remove it with the p_semaphore_free() call. After that, create it again.
+ *
+ * You can also do the same thing upon semaphore creation passing
+ * #P_SEM_ACCESS_CREATE to p_semaphore_new(). The only difference is that you
+ * should already know whether this semaphore object is from the previous crash
+ * or not.
+ */
+P_LIB_API void p_semaphore_take_ownership (PSemaphore *sem);
+
+/**
+ * @brief Acquires (P operation) a semaphore.
+ * @param sem #PSemaphore to acquire.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_semaphore_acquire (PSemaphore *sem,
+ PError **error);
+
+/**
+ * @brief Releases (V operation) a semaphore.
+ * @param sem #PSemaphore to release.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_semaphore_release (PSemaphore *sem,
+ PError **error);
+
+/**
+ * @brief Frees #PSemaphore object.
+ * @param sem #PSemaphore to free.
+ * @since 0.0.1
+ *
+ * It doesn't release an acquired semaphore, be careful to not to make a
+ * deadlock while removing the acquired semaphore.
+ */
+P_LIB_API void p_semaphore_free (PSemaphore *sem);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSEMAPHORE_H */
diff --git a/3rdparty/plibsys/src/pshm-amiga.c b/3rdparty/plibsys/src/pshm-amiga.c
new file mode 100644
index 0000000..4010ea2
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-amiga.c
@@ -0,0 +1,274 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "pshm.h"
+#include "pipc-private.h"
+
+#include <string.h>
+
+#include <exec/types.h>
+#include <proto/exec.h>
+
+#define P_SHM_NAMESPACE "pshm"
+#define P_SHM_SUFFIX "_p_shm_object"
+#define P_SHM_PRIV_SIZE (2 * sizeof (psize))
+
+struct PShm_ {
+ pboolean is_owner;
+ pchar *platform_key;
+ ppointer addr;
+ psize size;
+ PSemaphore *sem;
+ PShmAccessPerms perms;
+};
+
+static PErrorIPC pp_shm_get_ipc_error (puint32 err_code);
+static pboolean pp_shm_create_handle (PShm *shm, PError **error);
+
+static PErrorIPC
+pp_shm_get_ipc_error (puint32 err_code)
+{
+ if (err_code == ANMERROR_NOERROR)
+ return P_ERROR_IPC_NONE;
+ else if (err_code == ANMERROR_NOMEMORY)
+ return P_ERROR_IPC_NO_RESOURCES;
+ else if (err_code == ANMERROR_DUPLICATENAME)
+ return P_ERROR_IPC_EXISTS;
+ else if (err_code == ANMERROR_PARAMETER)
+ return P_ERROR_IPC_INVALID_ARGUMENT;
+ else
+ return P_ERROR_IPC_FAILED;
+}
+
+static pboolean
+pp_shm_create_handle (PShm *shm,
+ PError **error)
+{
+ ppointer mem_area;
+ puint32 err_code;
+ pboolean is_exists;
+
+ if (P_UNLIKELY (shm == NULL || shm->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ IExec->Forbid ();
+
+ mem_area = IExec->FindNamedMemory (P_SHM_NAMESPACE, shm->platform_key);
+
+ if (mem_area == NULL) {
+ mem_area = IExec->AllocNamedMemoryTags (shm->size + P_SHM_PRIV_SIZE,
+ P_SHM_NAMESPACE,
+ shm->platform_key,
+ ANMT_Error, &err_code,
+ TAG_END);
+
+ if (P_UNLIKELY (mem_area == NULL)) {
+ IExec->Permit ();
+ p_error_set_error_p (error,
+ (pint) pp_shm_get_ipc_error (err_code),
+ (pint) err_code,
+ "Failed to call AllocNamedMemoryTags() to create memory segment");
+ return FALSE;
+ }
+
+ memset (mem_area, 0, shm->size + P_SHM_PRIV_SIZE);
+
+ /* Set size and counter */
+ *((psize *) mem_area) = shm->size;
+ *((psize *) mem_area + 1) = 1;
+
+ is_exists = FALSE;
+ } else {
+ *((psize *) mem_area + 1) += 1;
+
+ shm->size = *((psize *) mem_area);
+ is_exists = TRUE;
+ }
+
+ shm->addr = ((pchar *) mem_area) + P_SHM_PRIV_SIZE;
+
+ if (P_UNLIKELY ((shm->sem = p_semaphore_new (shm->platform_key, 1,
+ is_exists ? P_SEM_ACCESS_OPEN : P_SEM_ACCESS_CREATE,
+ error)) == NULL)) {
+ IExec->FreeNamedMemory (P_SHM_NAMESPACE, shm->platform_key);
+ IExec->Permit ();
+ return FALSE;
+ }
+
+ IExec->Permit ();
+
+ return TRUE;
+}
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ PShm *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared segment");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for segment name");
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SHM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->perms = perms;
+ ret->size = size;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) {
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ if (P_LIKELY (ret->size > size && size != 0))
+ ret->size = size;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ shm->is_owner = TRUE;
+ p_semaphore_take_ownership (shm->sem);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ if (shm->addr != NULL) {
+ IExec->Forbid ();
+
+ *((psize *) shm->addr - 1) -= 1;
+
+ if (shm->is_owner || *((psize *) shm->addr - 1) == 0) {
+ p_semaphore_free (shm->sem);
+ shm->sem = NULL;
+
+ IExec->FreeNamedMemory (P_SHM_NAMESPACE, shm->platform_key);
+ }
+
+ IExec->Permit ();
+ }
+
+ shm->is_owner = FALSE;
+ shm->addr = NULL;
+ shm->size = 0;
+
+ if (P_LIKELY (shm->platform_key != NULL))
+ p_free (shm->platform_key);
+
+ p_free (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_acquire (shm->sem, error);
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_release (shm->sem, error);
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return NULL;
+
+ return shm->addr;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return 0;
+
+ return shm->size;
+}
diff --git a/3rdparty/plibsys/src/pshm-none.c b/3rdparty/plibsys/src/pshm-none.c
new file mode 100644
index 0000000..17cf4a5
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-none.c
@@ -0,0 +1,94 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pshm.h"
+
+#include <stdlib.h>
+
+struct PShm_ {
+ pint hdl;
+};
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ P_UNUSED (name);
+ P_UNUSED (size);
+ P_UNUSED (perms);
+ P_UNUSED (error);
+
+ return NULL;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ P_UNUSED (shm);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ P_UNUSED (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ P_UNUSED (shm);
+ P_UNUSED (error);
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ P_UNUSED (shm);
+ P_UNUSED (error);
+
+ return FALSE;
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ P_UNUSED (shm);
+
+ return NULL;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ P_UNUSED (shm);
+
+ return 0;
+}
diff --git a/3rdparty/plibsys/src/pshm-os2.c b/3rdparty/plibsys/src/pshm-os2.c
new file mode 100644
index 0000000..92e0779
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-os2.c
@@ -0,0 +1,350 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "pshm.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define INCL_DOSMEMMGR
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSERRORS
+#include <os2.h>
+
+#define P_SHM_MEM_PREFIX "\\SHAREMEM\\"
+#define P_SHM_SEM_PREFIX "\\SEM32\\"
+#define P_SHM_SUFFIX "_p_shm_object"
+
+struct PShm_ {
+ pchar *platform_key;
+ ppointer addr;
+ psize size;
+ HMTX sem;
+ PShmAccessPerms perms;
+};
+
+static pboolean pp_shm_create_handle (PShm *shm, PError **error);
+static void pp_shm_clean_handle (PShm *shm);
+
+static pboolean
+pp_shm_create_handle (PShm *shm,
+ PError **error)
+{
+ pchar *mem_name;
+ pchar *sem_name;
+ APIRET ulrc;
+ ULONG flags;
+
+ if (P_UNLIKELY (shm == NULL || shm->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ flags = PAG_COMMIT | PAG_READ;
+
+ if (shm->perms != P_SHM_ACCESS_READONLY)
+ flags |= PAG_WRITE;
+
+ if (P_UNLIKELY ((mem_name = p_malloc0 (strlen (shm->platform_key) +
+ strlen (P_SHM_MEM_PREFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared memory name");
+ return FALSE;
+ }
+
+ strcpy (mem_name, P_SHM_MEM_PREFIX);
+ strcat (mem_name, shm->platform_key);
+
+ while ((ulrc = DosAllocSharedMem ((PPVOID) &shm->addr,
+ (PSZ) mem_name,
+ shm->size,
+ flags)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR && ulrc != ERROR_ALREADY_EXISTS)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosAllocSharedMem() to allocate shared memory");
+ p_free (mem_name);
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ if (ulrc == ERROR_ALREADY_EXISTS) {
+ ULONG real_size;
+ ULONG real_flags;
+
+ flags = (shm->perms == P_SHM_ACCESS_READONLY) ? PAG_READ : (PAG_WRITE | PAG_READ);
+
+ while ((ulrc = DosGetNamedSharedMem ((PPVOID) &shm->addr,
+ (PSZ) mem_name,
+ flags)) == ERROR_INTERRUPT)
+ ;
+
+ p_free (mem_name);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosGetNamedSharedMem() to get shared memory");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ real_size = (ULONG) shm->size;
+
+ while ((ulrc = DosQueryMem ((PVOID) shm->addr,
+ &real_size,
+ &real_flags)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosQueryMem() to get memory info");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ shm->size = (psize) real_size;
+ } else
+ p_free (mem_name);
+
+ if (P_UNLIKELY ((sem_name = p_malloc0 (strlen (shm->platform_key) +
+ strlen (P_SHM_SEM_PREFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared memory name");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ strcpy (sem_name, P_SHM_SEM_PREFIX);
+ strcat (sem_name, shm->platform_key);
+
+ ulrc = DosCreateMutexSem ((PSZ) sem_name, &shm->sem, 0, FALSE);
+
+ if (ulrc == ERROR_DUPLICATE_NAME)
+ ulrc = DosOpenMutexSem ((PSZ) sem_name, &shm->sem);
+
+ p_free (sem_name);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to call DosCreateMutexSem() to create a lock");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_shm_clean_handle (PShm *shm)
+{
+ APIRET ulrc;
+
+ if (P_UNLIKELY (shm->addr != NULL)) {
+ while ((ulrc = DosFreeMem ((PVOID) shm->addr)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR))
+ P_ERROR ("PShm::pp_shm_clean_handle: DosFreeMem() failed");
+
+ shm->addr = NULL;
+ }
+
+ if (P_LIKELY (shm->sem != NULLHANDLE)) {
+ if (P_UNLIKELY (DosCloseMutexSem (shm->sem) != NO_ERROR))
+ P_ERROR ("PShm::pp_shm_clean_handle: DosCloseMutexSem() failed");
+
+ shm->sem = NULLHANDLE;
+ }
+
+ shm->size = 0;
+}
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ PShm *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared segment");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for segment name");
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SHM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->perms = perms;
+ ret->size = size;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) {
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ if (P_LIKELY (ret->size > size && size != 0))
+ ret->size = size;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ P_UNUSED (shm);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ pp_shm_clean_handle (shm);
+
+ if (P_LIKELY (shm->platform_key != NULL))
+ p_free (shm->platform_key);
+
+ p_free (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ APIRET ulrc;
+
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ while ((ulrc = DosRequestMutexSem (shm->sem,
+ (ULONG) SEM_INDEFINITE_WAIT)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to lock memory segment");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ APIRET ulrc;
+
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ ulrc = DosReleaseMutexSem (shm->sem);
+
+ if (P_UNLIKELY (ulrc != NO_ERROR)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_ipc_from_system ((pint) ulrc),
+ (pint) ulrc,
+ "Failed to unlock memory segment");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return NULL;
+
+ return shm->addr;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return 0;
+
+ return shm->size;
+}
diff --git a/3rdparty/plibsys/src/pshm-posix.c b/3rdparty/plibsys/src/pshm-posix.c
new file mode 100644
index 0000000..3551b2c
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-posix.c
@@ -0,0 +1,311 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "pshm.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+#include "psysclose-private.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#define P_SHM_SUFFIX "_p_shm_object"
+#define P_SHM_INVALID_HDL -1
+
+struct PShm_ {
+ pboolean shm_created;
+ pchar *platform_key;
+ ppointer addr;
+ psize size;
+ PSemaphore *sem;
+ PShmAccessPerms perms;
+};
+
+static pboolean pp_shm_create_handle (PShm *shm, PError **error);
+static void pp_shm_clean_handle (PShm *shm);
+
+static pboolean
+pp_shm_create_handle (PShm *shm,
+ PError **error)
+{
+ pboolean is_exists;
+ pint fd, flags;
+ struct stat stat_buf;
+
+ if (P_UNLIKELY (shm == NULL || shm->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ is_exists = FALSE;
+
+ while ((fd = shm_open (shm->platform_key,
+ O_CREAT | O_EXCL | O_RDWR,
+ 0660)) == P_SHM_INVALID_HDL &&
+ p_error_get_last_system () == EINTR)
+ ;
+
+ if (fd == P_SHM_INVALID_HDL) {
+ if (p_error_get_last_system () == EEXIST) {
+ is_exists = TRUE;
+
+ while ((fd = shm_open (shm->platform_key,
+ O_RDWR,
+ 0660)) == P_SHM_INVALID_HDL &&
+ p_error_get_last_system () == EINTR)
+ ;
+ }
+ } else
+ shm->shm_created = TRUE;
+
+ if (P_UNLIKELY (fd == P_SHM_INVALID_HDL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call shm_open() to create memory segment");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ /* Try to get size of the existing file descriptor */
+ if (is_exists) {
+ if (P_UNLIKELY (fstat (fd, &stat_buf) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call fstat() to get memory segment size");
+
+ if (P_UNLIKELY (p_sys_close (fd) != 0))
+ P_WARNING ("PShm::pp_shm_create_handle: p_sys_close() failed(1)");
+
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ shm->size = (psize) stat_buf.st_size;
+ } else {
+ if (P_UNLIKELY ((ftruncate (fd, (off_t) shm->size)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call ftruncate() to set memory segment size");
+
+ if (P_UNLIKELY (p_sys_close (fd) != 0))
+ P_WARNING ("PShm::pp_shm_create_handle: p_sys_close() failed(2)");
+
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+ }
+
+ flags = (shm->perms == P_SHM_ACCESS_READONLY) ? PROT_READ : PROT_READ | PROT_WRITE;
+
+ if (P_UNLIKELY ((shm->addr = mmap (NULL, shm->size, flags, MAP_SHARED, fd, 0)) == (void *) -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call mmap() to map memory segment");
+ shm->addr = NULL;
+
+ if (P_UNLIKELY (p_sys_close (fd) != 0))
+ P_WARNING ("PShm::pp_shm_create_handle: p_sys_close() failed(3)");
+
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (p_sys_close (fd) != 0))
+ P_WARNING ("PShm::pp_shm_create_handle: p_sys_close() failed(4)");
+
+ if (P_UNLIKELY ((shm->sem = p_semaphore_new (shm->platform_key, 1,
+ is_exists ? P_SEM_ACCESS_OPEN : P_SEM_ACCESS_CREATE,
+ error)) == NULL)) {
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_shm_clean_handle (PShm *shm)
+{
+ if (P_UNLIKELY (shm->addr != NULL && munmap (shm->addr, shm->size) == -1))
+ P_ERROR ("PShm::pp_shm_clean_handle: munmap () failed");
+
+ if (shm->shm_created == TRUE && shm_unlink (shm->platform_key) == -1)
+ P_ERROR ("PShm::pp_shm_clean_handle: shm_unlink() failed");
+
+ if (P_LIKELY (shm->sem != NULL)) {
+ p_semaphore_free (shm->sem);
+ shm->sem = NULL;
+ }
+
+ shm->shm_created = FALSE;
+ shm->addr = NULL;
+ shm->size = 0;
+}
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ PShm *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared segment");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for segment name");
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SHM_SUFFIX);
+
+#if defined (P_OS_IRIX) || defined (P_OS_TRU64)
+ /* IRIX and Tru64 prefer filename styled IPC names */
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+#else
+ ret->platform_key = p_ipc_get_platform_key (new_name, TRUE);
+#endif
+ ret->perms = perms;
+ ret->size = size;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) {
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ if (P_LIKELY (ret->size > size && size != 0))
+ ret->size = size;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ shm->shm_created = TRUE;
+ p_semaphore_take_ownership (shm->sem);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ pp_shm_clean_handle (shm);
+
+ if (P_LIKELY (shm->platform_key != NULL))
+ p_free (shm->platform_key);
+
+ p_free (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_acquire (shm->sem, error);
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_release (shm->sem, error);
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return NULL;
+
+ return shm->addr;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return 0;
+
+ return shm->size;
+}
diff --git a/3rdparty/plibsys/src/pshm-sysv.c b/3rdparty/plibsys/src/pshm-sysv.c
new file mode 100644
index 0000000..d7e6434
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-sysv.c
@@ -0,0 +1,307 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "pshm.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <errno.h>
+
+#define P_SHM_SUFFIX "_p_shm_object"
+#define P_SHM_INVALID_HDL -1
+
+typedef pint pshm_hdl;
+
+struct PShm_ {
+ pboolean file_created;
+ key_t unix_key;
+ pchar *platform_key;
+ pshm_hdl shm_hdl;
+ ppointer addr;
+ psize size;
+ PSemaphore *sem;
+ PShmAccessPerms perms;
+};
+
+static pboolean pp_shm_create_handle (PShm *shm, PError **error);
+static void pp_shm_clean_handle (PShm *shm);
+
+static pboolean
+pp_shm_create_handle (PShm *shm,
+ PError **error)
+{
+ pboolean is_exists;
+ pint flags, built;
+ struct shmid_ds shm_stat;
+
+ if (P_UNLIKELY (shm == NULL || shm->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ is_exists = FALSE;
+
+ if (P_UNLIKELY ((built = p_ipc_unix_create_key_file (shm->platform_key)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to create key file");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ } else if (built == 0)
+ shm->file_created = TRUE;
+
+ if (P_UNLIKELY ((shm->unix_key = p_ipc_unix_get_ftok_key (shm->platform_key)) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to get unique IPC key");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ flags = (shm->perms == P_SHM_ACCESS_READONLY) ? 0444 : 0660;
+
+ if ((shm->shm_hdl = shmget (shm->unix_key,
+ shm->size,
+ IPC_CREAT | IPC_EXCL | flags)) == P_SHM_INVALID_HDL) {
+ if (p_error_get_last_system () == EEXIST) {
+ is_exists = TRUE;
+
+ shm->shm_hdl = shmget (shm->unix_key, 0, flags);
+ }
+ } else
+ shm->file_created = (built == 1);
+
+ if (P_UNLIKELY (shm->shm_hdl == P_SHM_INVALID_HDL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call shmget() to create memory segment");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (shmctl (shm->shm_hdl, IPC_STAT, &shm_stat) == -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call shmctl() to get memory segment size");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ shm->size = shm_stat.shm_segsz;
+
+ flags = (shm->perms == P_SHM_ACCESS_READONLY) ? SHM_RDONLY : 0;
+
+ if (P_UNLIKELY ((shm->addr = shmat (shm->shm_hdl, 0, flags)) == (void *) -1)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call shmat() to attach to the memory segment");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((shm->sem = p_semaphore_new (shm->platform_key, 1,
+ is_exists ? P_SEM_ACCESS_OPEN : P_SEM_ACCESS_CREATE,
+ error)) == NULL)) {
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_shm_clean_handle (PShm *shm)
+{
+ struct shmid_ds shm_stat;
+
+ if (P_LIKELY (shm->addr != NULL)) {
+ if (P_UNLIKELY (shmdt (shm->addr) == -1))
+ P_ERROR ("PShm::pp_shm_clean_handle: shmdt() failed");
+
+ if (P_UNLIKELY (shmctl (shm->shm_hdl, IPC_STAT, &shm_stat) == -1))
+ P_ERROR ("PShm::pp_shm_clean_handle: shmctl() with IPC_STAT failed");
+
+ if (P_UNLIKELY (shm_stat.shm_nattch == 0 && shmctl (shm->shm_hdl, IPC_RMID, 0) == -1))
+ P_ERROR ("PShm::pp_shm_clean_handle: shmctl() with IPC_RMID failed");
+ }
+
+ if (shm->file_created == TRUE && unlink (shm->platform_key) == -1)
+ P_ERROR ("PShm::pp_shm_clean_handle: unlink() failed");
+
+ if (P_LIKELY (shm->sem != NULL)) {
+ p_semaphore_free (shm->sem);
+ shm->sem = NULL;
+ }
+
+ shm->file_created = FALSE;
+ shm->unix_key = -1;
+ shm->shm_hdl = P_SHM_INVALID_HDL;
+ shm->addr = NULL;
+ shm->size = 0;
+}
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ PShm *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared segment");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for segment name");
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SHM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->perms = perms;
+ ret->size = size;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) {
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ if (P_LIKELY (ret->size > size && size != 0))
+ ret->size = size;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ shm->file_created = TRUE;
+ p_semaphore_take_ownership (shm->sem);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ pp_shm_clean_handle (shm);
+
+ if (P_LIKELY (shm->platform_key != NULL))
+ p_free (shm->platform_key);
+
+ p_free (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_acquire (shm->sem, error);
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_release (shm->sem, error);
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return NULL;
+
+ return shm->addr;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return 0;
+
+ return shm->size;
+}
diff --git a/3rdparty/plibsys/src/pshm-win.c b/3rdparty/plibsys/src/pshm-win.c
new file mode 100644
index 0000000..3ae11f9
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm-win.c
@@ -0,0 +1,262 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "pmem.h"
+#include "psemaphore.h"
+#include "pshm.h"
+#include "perror-private.h"
+#include "pipc-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define P_SHM_INVALID_HDL NULL
+#define P_SHM_SUFFIX "_p_shm_object"
+
+typedef HANDLE pshm_hdl;
+
+struct PShm_ {
+ pchar *platform_key;
+ pshm_hdl shm_hdl;
+ ppointer addr;
+ psize size;
+ PSemaphore *sem;
+ PShmAccessPerms perms;
+};
+
+static pboolean pp_shm_create_handle (PShm *shm, PError **error);
+static void pp_shm_clean_handle (PShm *shm);
+
+static pboolean
+pp_shm_create_handle (PShm *shm,
+ PError **error)
+{
+ pboolean is_exists;
+ MEMORY_BASIC_INFORMATION mem_stat;
+ DWORD protect;
+
+ if (P_UNLIKELY (shm == NULL || shm->platform_key == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ is_exists = FALSE;
+
+ protect = (shm->perms == P_SHM_ACCESS_READONLY) ? PAGE_READONLY : PAGE_READWRITE;
+
+ /* Multibyte character set must be enabled */
+ if (P_UNLIKELY ((shm->shm_hdl = CreateFileMappingA (INVALID_HANDLE_VALUE,
+ NULL,
+ protect,
+ 0,
+ (DWORD) shm->size,
+ shm->platform_key)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call CreateFileMapping() to create file mapping");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ protect = (protect == PAGE_READONLY) ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
+
+ if (P_UNLIKELY ((shm->addr = MapViewOfFile (shm->shm_hdl, protect, 0, 0, 0)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call MapViewOfFile() to map file to memory");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ if (p_error_get_last_system () == ERROR_ALREADY_EXISTS)
+ is_exists = TRUE;
+
+ if (P_UNLIKELY (VirtualQuery (shm->addr, &mem_stat, sizeof (mem_stat)) == 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_last_ipc (),
+ p_error_get_last_system (),
+ "Failed to call VirtualQuery() to get memory map info");
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ shm->size = mem_stat.RegionSize;
+
+ if (P_UNLIKELY ((shm->sem = p_semaphore_new (shm->platform_key, 1,
+ is_exists ? P_SEM_ACCESS_OPEN : P_SEM_ACCESS_CREATE,
+ error)) == NULL)) {
+ pp_shm_clean_handle (shm);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pp_shm_clean_handle (PShm *shm)
+{
+ if (P_UNLIKELY (shm->addr != NULL && UnmapViewOfFile ((char *) shm->addr) == 0))
+ P_ERROR ("PShm::pp_shm_clean_handle: UnmapViewOfFile() failed");
+
+ if (P_UNLIKELY (shm->shm_hdl != P_SHM_INVALID_HDL && CloseHandle (shm->shm_hdl) == 0))
+ P_ERROR ("PShm::pp_shm_clean_handle: CloseHandle() failed");
+
+ if (P_LIKELY (shm->sem != NULL)) {
+ p_semaphore_free (shm->sem);
+ shm->sem = NULL;
+ }
+
+ shm->shm_hdl = P_SHM_INVALID_HDL;
+ shm->addr = NULL;
+ shm->size = 0;
+}
+
+P_LIB_API PShm *
+p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error)
+{
+ PShm *ret;
+ pchar *new_name;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared segment");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for segment name");
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ strcpy (new_name, name);
+ strcat (new_name, P_SHM_SUFFIX);
+
+ ret->platform_key = p_ipc_get_platform_key (new_name, FALSE);
+ ret->perms = perms;
+ ret->size = size;
+
+ p_free (new_name);
+
+ if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) {
+ p_shm_free (ret);
+ return NULL;
+ }
+
+ if (P_LIKELY (ret->size > size && size != 0))
+ ret->size = size;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_take_ownership (PShm *shm)
+{
+ P_UNUSED (shm);
+}
+
+P_LIB_API void
+p_shm_free (PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return;
+
+ pp_shm_clean_handle (shm);
+
+ if (P_LIKELY (shm->platform_key != NULL))
+ p_free (shm->platform_key);
+
+ p_free (shm);
+}
+
+P_LIB_API pboolean
+p_shm_lock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_acquire (shm->sem, error);
+}
+
+P_LIB_API pboolean
+p_shm_unlock (PShm *shm,
+ PError **error)
+{
+ if (P_UNLIKELY (shm == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ return p_semaphore_release (shm->sem, error);
+}
+
+P_LIB_API ppointer
+p_shm_get_address (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return NULL;
+
+ return shm->addr;
+}
+
+P_LIB_API psize
+p_shm_get_size (const PShm *shm)
+{
+ if (P_UNLIKELY (shm == NULL))
+ return 0;
+
+ return shm->size;
+}
diff --git a/3rdparty/plibsys/src/pshm.h b/3rdparty/plibsys/src/pshm.h
new file mode 100644
index 0000000..096c009
--- /dev/null
+++ b/3rdparty/plibsys/src/pshm.h
@@ -0,0 +1,195 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pshm.h
+ * @brief Shared memory
+ * @author Alexander Saprykin
+ *
+ * Shared memory is a memory segment which can be accessed from several threads
+ * or processes. It provides an efficient way to transfer large blocks of data
+ * between processes. It can be used as any other regular memory segment in an
+ * application.
+ *
+ * Shared memory acts like an inter-process communication method. This memory
+ * exchange implementation is process-wide so you can transfer data not only
+ * between the threads. But it makes this IPC method (actually like any other
+ * IPC method, as well) relatively heavy. Consider using other approaches
+ * instead if you do not need to cross the process boundary.
+ *
+ * A shared memory segment doesn't provide any synchronization primitives itself
+ * which means that several processes or threads can concurrently write and read
+ * from it. This can lead to data consistency problems. To avoid such situations
+ * a locking mechanism is provided: use p_shm_lock() before entering a critical
+ * section on the memory segment and p_shm_unlock() when leaving this section.
+ * The locking mechanism is working across the process boundary.
+ *
+ * A process-wide shared memory segment is identified by its name across the
+ * system, thus it is also called a named memory segment. Use p_shm_new() to
+ * open the named shared memory segment and p_shm_free() to close it.
+ *
+ * Please note the following platform specific differences:
+ *
+ * - Windows and OS/2 don't own IPC objects (processes own them), which means
+ * that a shared memory segment will be removed after the last process or thread
+ * detaches (or after terminating all the processes and threads attached to the
+ * segment) it.
+ *
+ * - UNIX systems own IPC objects. Because of that UNIX IPC objects can survive
+ * an application crash: the attached shared memory segment can contain data
+ * from the previous working session. This could happen if you have not detached
+ * from all the shared memory segments explicitly before terminating the
+ * application.
+ *
+ * - HP-UX has limitations due to its MPAS/MGAS features, so you couldn't attach
+ * to the same memory segment twice from the same process.
+ *
+ * - IRIX allows to open several instances of the same buffer within the single
+ * process, but it will close the object after the first close call from any of
+ * the threads within the process.
+ *
+ * - OpenVMS (as of 8.4 release) has broken implementation of process-wide named
+ * semaphores which leads to the broken shared memory also.
+ *
+ * - Syllable lacks support for process-wide named semaphores which leads to the
+ * absence of shared memory.
+ *
+ * - BeOS lacks support for process-wide named semaphores which leads to the
+ * absence of shared memory.
+ *
+ * You can take ownership of the shared memory segment with
+ * p_shm_take_ownership() to explicitly remove it from the system after closing.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSHM_H
+#define PLIBSYS_HEADER_PSHM_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Enum with shared memory access permissions. */
+typedef enum PShmAccessPerms_ {
+ P_SHM_ACCESS_READONLY = 0, /**< Read-only access. */
+ P_SHM_ACCESS_READWRITE = 1 /**< Read/write access. */
+} PShmAccessPerms;
+
+/** Shared memory opaque data structure. */
+typedef struct PShm_ PShm;
+
+/**
+ * @brief Creates a new #PShm object.
+ * @param name Shared memory name.
+ * @param size Size of the memory segment in bytes, can't be changed later.
+ * @param perms Memory segment permissions, see #PShmAccessPerms.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to a newly created #PShm object in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PShm * p_shm_new (const pchar *name,
+ psize size,
+ PShmAccessPerms perms,
+ PError **error);
+
+/**
+ * @brief Takes ownership of a shared memory segment.
+ * @param shm Shared memory segment.
+ * @since 0.0.1
+ *
+ * If you take ownership of the shared memory object, p_shm_free() will try to
+ * completely unlink it and remove from the system. This is useful on UNIX
+ * systems where shared memory can survive an application crash. On the Windows
+ * and OS/2 platforms this call has no effect.
+ *
+ * The common usage of this call is upon application startup to ensure that the
+ * memory segment from the previous crash will be unlinked from the system. To
+ * do that, call p_shm_new() and check if its condition is normal (the segment
+ * size, the data). If not, take ownership of the shared memory object and
+ * remove it with the p_shm_free() call. After that, create it again.
+ */
+P_LIB_API void p_shm_take_ownership (PShm *shm);
+
+/**
+ * @brief Frees #PShm object.
+ * @param shm #PShm to free.
+ * @since 0.0.1
+ *
+ * It doesn't unlock a given shared memory segment, be careful to not to make a
+ * deadlock or a segfault while freeing the memory segment which is under usage.
+ */
+P_LIB_API void p_shm_free (PShm *shm);
+
+/**
+ * @brief Locks #PShm object for usage.
+ * @param shm #PShm to lock.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * If the object is already locked then the thread will be suspended until the
+ * object becomes unlocked.
+ */
+P_LIB_API pboolean p_shm_lock (PShm *shm,
+ PError **error);
+
+/**
+ * @brief Unlocks #PShm object.
+ * @param shm #PShm to unlock.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_shm_unlock (PShm *shm,
+ PError **error);
+
+/**
+ * @brief Gets a starting address of a #PShm memory segment.
+ * @param shm #PShm to get the address for.
+ * @return Pointer to the starting address in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_shm_get_address (const PShm *shm);
+
+/**
+ * @brief Gets the size of a #PShm memory segment.
+ * @param shm #PShm to get the size for.
+ * @return Size of the given memory segment in case of success, 0 otherwise.
+ * @since 0.0.1
+ *
+ * Note that the returned size would be a slightly larger than specified during
+ * the p_shm_new() call due to service information stored inside.
+ */
+P_LIB_API psize p_shm_get_size (const PShm *shm);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSHM_H */
diff --git a/3rdparty/plibsys/src/pshmbuffer.c b/3rdparty/plibsys/src/pshmbuffer.c
new file mode 100644
index 0000000..7bdbbd3
--- /dev/null
+++ b/3rdparty/plibsys/src/pshmbuffer.c
@@ -0,0 +1,334 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2020 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pshm.h"
+#include "pshmbuffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define P_SHM_BUFFER_READ_OFFSET 0
+#define P_SHM_BUFFER_WRITE_OFFSET sizeof (psize)
+#define P_SHM_BUFFER_DATA_OFFSET sizeof (psize) * 2
+
+struct PShmBuffer_ {
+ PShm *shm;
+ psize size;
+};
+
+static psize pp_shm_buffer_get_free_space (PShmBuffer *buf);
+static psize pp_shm_buffer_get_used_space (PShmBuffer *buf);
+
+/* Warning: this function is not thread-safe, only for internal usage */
+static psize
+pp_shm_buffer_get_free_space (PShmBuffer *buf)
+{
+ psize read_pos, write_pos;
+ ppointer addr;
+
+ addr = p_shm_get_address (buf->shm);
+
+ memcpy (&read_pos, (pchar *) addr + P_SHM_BUFFER_READ_OFFSET, sizeof (read_pos));
+ memcpy (&write_pos, (pchar *) addr + P_SHM_BUFFER_WRITE_OFFSET, sizeof (write_pos));
+
+ if (write_pos < read_pos)
+ return read_pos - write_pos - 1;
+ else if (write_pos > read_pos)
+ return buf->size - (write_pos - read_pos) - 1;
+ else
+ return buf->size - 1;
+}
+
+static psize
+pp_shm_buffer_get_used_space (PShmBuffer *buf)
+{
+ psize read_pos, write_pos;
+ ppointer addr;
+
+ addr = p_shm_get_address (buf->shm);
+
+ memcpy (&read_pos, (pchar *) addr + P_SHM_BUFFER_READ_OFFSET, sizeof (read_pos));
+ memcpy (&write_pos, (pchar *) addr + P_SHM_BUFFER_WRITE_OFFSET, sizeof (write_pos));
+
+ if (write_pos > read_pos)
+ return write_pos - read_pos;
+ else if (write_pos < read_pos)
+ return (buf->size - (read_pos - write_pos));
+ else
+ return 0;
+}
+
+P_LIB_API PShmBuffer *
+p_shm_buffer_new (const pchar *name,
+ psize size,
+ PError **error)
+{
+ PShmBuffer *ret;
+ PShm *shm;
+
+ if (P_UNLIKELY (name == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((shm = p_shm_new (name,
+ (size != 0) ? size + P_SHM_BUFFER_DATA_OFFSET + 1 : 0,
+ P_SHM_ACCESS_READWRITE,
+ error)) == NULL))
+ return NULL;
+
+ if (P_UNLIKELY (p_shm_get_size (shm) <= P_SHM_BUFFER_DATA_OFFSET + 1)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Too small memory segment to hold required data");
+ p_shm_free (shm);
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShmBuffer))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for shared buffer");
+ p_shm_free (shm);
+ return NULL;
+ }
+
+ ret->shm = shm;
+ ret->size = p_shm_get_size (shm) - P_SHM_BUFFER_DATA_OFFSET;
+
+ return ret;
+}
+
+P_LIB_API void
+p_shm_buffer_free (PShmBuffer *buf)
+{
+ if (P_UNLIKELY (buf == NULL))
+ return;
+
+ p_shm_free (buf->shm);
+ p_free (buf);
+}
+
+P_LIB_API void
+p_shm_buffer_take_ownership (PShmBuffer *buf)
+{
+ if (P_UNLIKELY (buf == NULL))
+ return;
+
+ p_shm_take_ownership (buf->shm);
+}
+
+P_LIB_API pint
+p_shm_buffer_read (PShmBuffer *buf,
+ ppointer storage,
+ psize len,
+ PError **error)
+{
+ psize read_pos, write_pos;
+ psize data_aval, to_copy;
+ puint i;
+ ppointer addr;
+
+ if (P_UNLIKELY (buf == NULL || storage == NULL || len == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY ((addr = p_shm_get_address (buf->shm)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Unable to get shared memory address");
+ return -1;
+ }
+
+ if (P_UNLIKELY (p_shm_lock (buf->shm, error) == FALSE))
+ return -1;
+
+ memcpy (&read_pos, (pchar *) addr + P_SHM_BUFFER_READ_OFFSET, sizeof (read_pos));
+ memcpy (&write_pos, (pchar *) addr + P_SHM_BUFFER_WRITE_OFFSET, sizeof (write_pos));
+
+ if (read_pos == write_pos) {
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return 0;
+ }
+
+ data_aval = pp_shm_buffer_get_used_space (buf);
+ to_copy = (data_aval <= len) ? data_aval : len;
+
+ for (i = 0; i < to_copy; ++i)
+ memcpy ((pchar *) storage + i,
+ (pchar *) addr + P_SHM_BUFFER_DATA_OFFSET + ((read_pos + i) % buf->size),
+ 1);
+
+ read_pos = (read_pos + to_copy) % buf->size;
+ memcpy ((pchar *) addr + P_SHM_BUFFER_READ_OFFSET, &read_pos, sizeof (read_pos));
+
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return (pint) to_copy;
+}
+
+P_LIB_API pssize
+p_shm_buffer_write (PShmBuffer *buf,
+ ppointer data,
+ psize len,
+ PError **error)
+{
+ psize read_pos, write_pos;
+ puint i;
+ ppointer addr;
+
+ if (P_UNLIKELY (buf == NULL || data == NULL || len == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY ((addr = p_shm_get_address (buf->shm)) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Unable to get shared memory address");
+ return -1;
+ }
+
+ if (P_UNLIKELY (p_shm_lock (buf->shm, error) == FALSE))
+ return -1;
+
+ memcpy (&read_pos, (pchar *) addr + P_SHM_BUFFER_READ_OFFSET, sizeof (read_pos));
+ memcpy (&write_pos, (pchar *) addr + P_SHM_BUFFER_WRITE_OFFSET, sizeof (write_pos));
+
+ if (pp_shm_buffer_get_free_space (buf) < len) {
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return 0;
+ }
+
+ for (i = 0; i < len; ++i)
+ memcpy ((pchar *) addr + P_SHM_BUFFER_DATA_OFFSET + ((write_pos + i) % buf->size),
+ (pchar *) data + i,
+ 1);
+
+ write_pos = (write_pos + len) % buf->size;
+ memcpy ((pchar *) addr + P_SHM_BUFFER_WRITE_OFFSET, &write_pos, sizeof (write_pos));
+
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return (pssize) len;
+}
+
+P_LIB_API pssize
+p_shm_buffer_get_free_space (PShmBuffer *buf,
+ PError **error)
+{
+ psize space;
+
+ if (P_UNLIKELY (buf == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY (p_shm_lock (buf->shm, error) == FALSE))
+ return -1;
+
+ space = pp_shm_buffer_get_free_space (buf);
+
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return (pssize) space;
+}
+
+P_LIB_API pssize
+p_shm_buffer_get_used_space (PShmBuffer *buf,
+ PError **error)
+{
+ psize space;
+
+ if (P_UNLIKELY (buf == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IPC_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY (p_shm_lock (buf->shm, error) == FALSE))
+ return -1;
+
+ space = pp_shm_buffer_get_used_space (buf);
+
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, error) == FALSE))
+ return -1;
+
+ return (pssize) space;
+}
+
+P_LIB_API void
+p_shm_buffer_clear (PShmBuffer *buf)
+{
+ ppointer addr;
+ psize size;
+
+ if (P_UNLIKELY (buf == NULL))
+ return;
+
+ if (P_UNLIKELY ((addr = p_shm_get_address (buf->shm)) == NULL)) {
+ P_ERROR ("PShmBuffer::p_shm_buffer_clear: p_shm_get_address() failed");
+ return;
+ }
+
+ size = p_shm_get_size (buf->shm);
+
+ if (P_UNLIKELY (p_shm_lock (buf->shm, NULL) == FALSE)) {
+ P_ERROR ("PShmBuffer::p_shm_buffer_clear: p_shm_lock() failed");
+ return;
+ }
+
+ memset (addr, 0, size);
+
+ if (P_UNLIKELY (p_shm_unlock (buf->shm, NULL) == FALSE))
+ P_ERROR ("PShmBuffer::p_shm_buffer_clear: p_shm_unlock() failed");
+}
diff --git a/3rdparty/plibsys/src/pshmbuffer.h b/3rdparty/plibsys/src/pshmbuffer.h
new file mode 100644
index 0000000..5c8bcc1
--- /dev/null
+++ b/3rdparty/plibsys/src/pshmbuffer.h
@@ -0,0 +1,191 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pshmbuffer.h
+ * @brief Shared memory buffer
+ * @author Alexander Saprykin
+ *
+ * A shared memory buffer works like any other buffer but it is built upon a
+ * shared memory region instead of the process-only address space. Thus it
+ * inherits all the advantages and disadvantages of shared memory behavior. You
+ * should read about #PShm before using this buffer implementation to understand
+ * underlying restrictions.
+ *
+ * The shared memory buffer is process-wide and identified by its name across
+ * the system, thus it can be opened by any process if it knows its name. Use
+ * p_shm_buffer_new() to open the shared memory buffer and p_shm_buffer_free()
+ * to close it.
+ *
+ * All read/write operations are completely thread- and process-safe, which
+ * means that no other synchronization primitive is required, even for inter-
+ * process access. A #PShm locking mechanism is used for access synchronization.
+ *
+ * The buffer is cyclic and non-overridable which means that you wouldn't get
+ * buffer overflow and wouldn't override previously written data until reading
+ * it.
+ *
+ * The read operation checks whether there is any data available and reads it in
+ * case of successful check. After reading the data used space in the buffer is
+ * marked as free and any subsequent write operation may overwrite it. Thus you
+ * couldn't read the same data twice. The read operation is performed with the
+ * p_shm_buffer_read() call.
+ *
+ * The write operation checks whether there is enough free space available and
+ * writes a given memory block only if the buffer has enough free space.
+ * Otherwise no data is written. The write operation is performed with the
+ * p_shm_buffer_write() call.
+ *
+ * Data can be read and written into the buffer only sequentially. There is no
+ * way to access an arbitrary address inside the buffer.
+ *
+ * You can take ownership of the shared memory buffer with
+ * p_shm_buffer_take_ownership() to explicitly remove it from the system after
+ * closing. Please refer to the #PShm description to understand the intention of
+ * this action.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSHMBUFFER_H
+#define PLIBSYS_HEADER_PSHMBUFFER_H
+
+#include <ptypes.h>
+#include <pmacros.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Shared memory buffer opaque data structure. */
+typedef struct PShmBuffer_ PShmBuffer;
+
+/**
+ * @brief Creates a new #PShmBuffer structure.
+ * @param name Unique buffer name.
+ * @param size Buffer size in bytes, can't be changed later.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to the #PShmBuffer structure in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ *
+ * If a buffer with the same name already exists then the @a size will be
+ * ignored and the existing buffer will be returned.
+ */
+P_LIB_API PShmBuffer * p_shm_buffer_new (const pchar *name,
+ psize size,
+ PError **error);
+
+/**
+ * @brief Frees #PShmBuffer structure.
+ * @param buf #PShmBuffer to free.
+ * @since 0.0.1
+ *
+ * Note that a buffer will be completely removed from the system only after the
+ * last instance of the buffer with the same name is closed.
+ */
+P_LIB_API void p_shm_buffer_free (PShmBuffer *buf);
+
+/**
+ * @brief Takes ownership of a shared memory buffer.
+ * @param buf Shared memory buffer.
+ * @since 0.0.1
+ *
+ * If you take ownership of the shared memory buffer, p_shm_buffer_free() will
+ * try to completely unlink it and remove from the system. This is useful on
+ * UNIX systems, where shared memory can survive an application crash. On the
+ * Windows and OS/2 platforms this call has no effect.
+ *
+ * The common usage of this call is upon application startup to ensure that the
+ * memory segment from the previous crash can be removed from the system. To do
+ * that, call p_shm_buffer_new() and check if its condition is normal (used
+ * space, free space). If not, take ownership of the shared memory buffer object
+ * and remove it with the p_shm_buffer_free() call. After that, create it again.
+ */
+P_LIB_API void p_shm_buffer_take_ownership (PShmBuffer *buf);
+
+/**
+ * @brief Tries to read data from a shared memory buffer.
+ * @param buf #PShmBuffer to read data from.
+ * @param[out] storage Output buffer to put data in.
+ * @param len Storage size in bytes.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Number of read bytes (can be 0 if buffer is empty), or -1 if error
+ * occured.
+ * @since 0.0.1
+ */
+P_LIB_API pint p_shm_buffer_read (PShmBuffer *buf,
+ ppointer storage,
+ psize len,
+ PError **error);
+
+/**
+ * @brief Tries to write data into a shared memory buffer.
+ * @param buf #PShmBuffer to write data into.
+ * @param data Data to write.
+ * @param len Data size in bytes.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Number of written bytes (can be 0 if buffer is full), or -1 if error
+ * occured.
+ * @since 0.0.1
+ * @note Write operation is performed only if the buffer has enough space for
+ * the given data size.
+ */
+P_LIB_API pssize p_shm_buffer_write (PShmBuffer *buf,
+ ppointer data,
+ psize len,
+ PError **error);
+
+/**
+ * @brief Gets free space in the shared memory buffer.
+ * @param buf #PShmBuffer to check space in.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Free space in bytes in case of success, -1 otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pssize p_shm_buffer_get_free_space (PShmBuffer *buf,
+ PError **error);
+
+/**
+ * @brief Gets used space in the shared memory buffer.
+ * @param buf #PShmBuffer to check space in.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Used space in bytes in case of success, -1 otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pssize p_shm_buffer_get_used_space (PShmBuffer *buf,
+ PError **error);
+
+/**
+ * @brief Clears all data in the buffer and fills it with zeros.
+ * @param buf #PShmBuffer to clear.
+ * @since 0.0.1
+ */
+P_LIB_API void p_shm_buffer_clear (PShmBuffer *buf);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSHMBUFFER_H */
diff --git a/3rdparty/plibsys/src/psocket.c b/3rdparty/plibsys/src/psocket.c
new file mode 100644
index 0000000..fb04379
--- /dev/null
+++ b/3rdparty/plibsys/src/psocket.c
@@ -0,0 +1,1644 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ * Some workarounds have been used from Glib (comments are kept)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "psocket.h"
+#ifdef P_OS_SCO
+# include "ptimeprofiler.h"
+#endif
+#include "perror-private.h"
+#include "plibsys-private.h"
+#include "psysclose-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef P_OS_WIN
+# include <fcntl.h>
+# include <errno.h>
+# include <unistd.h>
+# include <signal.h>
+# ifdef P_OS_VMS
+# include <stropts.h>
+# endif
+#endif
+
+#ifndef P_OS_WIN
+# if defined (P_OS_BEOS) || defined (P_OS_MAC) || defined (P_OS_MAC9) || \
+ defined (P_OS_OS2) || defined (P_OS_AMIGA)
+# define P_SOCKET_USE_SELECT
+# include <sys/select.h>
+# include <sys/time.h>
+# else
+# define P_SOCKET_USE_POLL
+# include <sys/poll.h>
+# endif
+#endif
+
+/* On old Solaris systems SOMAXCONN is set to 5 */
+#define P_SOCKET_DEFAULT_BACKLOG 5
+
+struct PSocket_ {
+ PSocketFamily family;
+ PSocketProtocol protocol;
+ PSocketType type;
+ pint fd;
+ pint listen_backlog;
+ pint timeout;
+ puint blocking : 1;
+ puint keepalive : 1;
+ puint closed : 1;
+ puint connected : 1;
+ puint listening : 1;
+#ifdef P_OS_WIN
+ WSAEVENT events;
+#endif
+#ifdef P_OS_SCO
+ PTimeProfiler *timer;
+#endif
+};
+
+#ifndef SHUT_RD
+# define SHUT_RD 0
+#endif
+
+#ifndef SHUT_WR
+# define SHUT_WR 1
+#endif
+
+#ifndef SHUT_RDWR
+# define SHUT_RDWR 2
+#endif
+
+#ifdef MSG_NOSIGNAL
+# define P_SOCKET_DEFAULT_SEND_FLAGS MSG_NOSIGNAL
+#else
+# define P_SOCKET_DEFAULT_SEND_FLAGS 0
+#endif
+
+static pboolean pp_socket_set_fd_blocking (pint fd, pboolean blocking, PError **error);
+static pboolean pp_socket_check (const PSocket *socket, PError **error);
+static pboolean pp_socket_set_details_from_fd (PSocket *socket, PError **error);
+
+static pboolean
+pp_socket_set_fd_blocking (pint fd,
+ pboolean blocking,
+ PError **error)
+{
+#ifndef P_OS_WIN
+ pint32 arg;
+#else
+ pulong arg;
+#endif
+
+#ifndef P_OS_WIN
+# ifdef P_OS_VMS
+ arg = !blocking;
+# if (PLIBSYS_SIZEOF_VOID_P == 8)
+# pragma __pointer_size 32
+# endif
+ /* Explicit (void *) cast is necessary */
+ if (P_UNLIKELY (ioctl (fd, FIONBIO, (void *) &arg) < 0)) {
+# if (PLIBSYS_SIZEOF_VOID_P == 8)
+# pragma __pointer_size 64
+# endif
+# else
+ if (P_UNLIKELY ((arg = fcntl (fd, F_GETFL, NULL)) < 0)) {
+ P_WARNING ("PSocket::pp_socket_set_fd_blocking: fcntl() failed");
+ arg = 0;
+ }
+
+ arg = (!blocking) ? (arg | O_NONBLOCK) : (arg & ~O_NONBLOCK);
+
+ if (P_UNLIKELY (fcntl (fd, F_SETFL, arg) < 0)) {
+# endif
+#else
+ arg = !blocking;
+
+ if (P_UNLIKELY (ioctlsocket (fd, FIONBIO, &arg) == SOCKET_ERROR)) {
+#endif
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to set socket blocking flags");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_socket_check (const PSocket *socket,
+ PError **error)
+{
+ if (P_UNLIKELY (socket->closed)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NOT_AVAILABLE,
+ 0,
+ "Socket is already closed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static pboolean
+pp_socket_set_details_from_fd (PSocket *socket,
+ PError **error)
+{
+#ifdef SO_DOMAIN
+ PSocketFamily family;
+#endif
+ struct sockaddr_storage address;
+ pint fd, value;
+ socklen_t addrlen, optlen;
+#ifdef P_OS_WIN
+ /* See comment below */
+ BOOL bool_val = FALSE;
+#else
+ pint bool_val;
+#endif
+
+ fd = socket->fd;
+ optlen = sizeof (value);
+
+ if (P_UNLIKELY (getsockopt (fd, SOL_SOCKET, SO_TYPE, (ppointer) &value, &optlen) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getsockopt() to get socket info for fd");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (optlen != sizeof (value))) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Failed to get socket info for fd, bad option length");
+ return FALSE;
+ }
+
+ switch (value) {
+ case SOCK_STREAM:
+ socket->type = P_SOCKET_TYPE_STREAM;
+ break;
+
+ case SOCK_DGRAM:
+ socket->type = P_SOCKET_TYPE_DATAGRAM;
+ break;
+
+#ifdef SOCK_SEQPACKET
+ case SOCK_SEQPACKET:
+ socket->type = P_SOCKET_TYPE_SEQPACKET;
+ break;
+#endif
+
+ default:
+ socket->type = P_SOCKET_TYPE_UNKNOWN;
+ break;
+ }
+
+ addrlen = sizeof (address);
+
+ if (P_UNLIKELY (getsockname (fd, (struct sockaddr *) &address, &addrlen) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getsockname() to get socket address info");
+ return FALSE;
+ }
+
+#ifdef SO_DOMAIN
+ if (!(addrlen > 0)) {
+ optlen = sizeof (family);
+
+ if (P_UNLIKELY (getsockopt (socket->fd,
+ SOL_SOCKET,
+ SO_DOMAIN,
+ (ppointer) &family,
+ &optlen) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getsockopt() to get socket SO_DOMAIN option");
+ return FALSE;
+ }
+ }
+#endif
+
+ switch (address.ss_family) {
+ case P_SOCKET_FAMILY_INET:
+ socket->family = P_SOCKET_FAMILY_INET;
+ break;
+#ifdef AF_INET6
+ case P_SOCKET_FAMILY_INET6:
+ socket->family = P_SOCKET_FAMILY_INET6;
+ break;
+#endif
+ default:
+ socket->family = P_SOCKET_FAMILY_UNKNOWN;
+ break;
+ }
+
+#ifdef AF_INET6
+ if (socket->family == P_SOCKET_FAMILY_INET6 || socket->family == P_SOCKET_FAMILY_INET) {
+#else
+ if (socket->family == P_SOCKET_FAMILY_INET) {
+#endif
+ switch (socket->type) {
+ case P_SOCKET_TYPE_STREAM:
+ socket->protocol = P_SOCKET_PROTOCOL_TCP;
+ break;
+ case P_SOCKET_TYPE_DATAGRAM:
+ socket->protocol = P_SOCKET_PROTOCOL_UDP;
+ break;
+ case P_SOCKET_TYPE_SEQPACKET:
+ socket->protocol = P_SOCKET_PROTOCOL_SCTP;
+ break;
+ case P_SOCKET_TYPE_UNKNOWN:
+ break;
+ }
+ }
+
+ if (P_LIKELY (socket->family != P_SOCKET_FAMILY_UNKNOWN)) {
+ addrlen = sizeof (address);
+
+ if (getpeername (fd, (struct sockaddr *) &address, &addrlen) >= 0)
+ socket->connected = TRUE;
+ }
+
+ optlen = sizeof (bool_val);
+
+ if (getsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, (ppointer) &bool_val, &optlen) == 0) {
+#ifndef P_OS_WIN
+ /* Experimentation indicates that the SO_KEEPALIVE value is
+ * actually a char on Windows, even if documentation claims it
+ * to be a BOOL which is a typedef for int. */
+ if (optlen != sizeof (bool_val))
+ P_WARNING ("PSocket::pp_socket_set_details_from_fd: getsockopt() with SO_KEEPALIVE failed");
+#endif
+ socket->keepalive = !!bool_val;
+ } else
+ /* Can't read, maybe not supported, assume FALSE */
+ socket->keepalive = FALSE;
+
+ return TRUE;
+}
+
+pboolean
+p_socket_init_once (void)
+{
+#ifdef P_OS_WIN
+ WORD ver_req;
+ WSADATA wsa_data;
+
+ ver_req = MAKEWORD (2, 2);
+
+ if (P_UNLIKELY (WSAStartup (ver_req, &wsa_data) != 0))
+ return FALSE;
+
+ if (P_UNLIKELY (LOBYTE (wsa_data.wVersion) != 2 || HIBYTE (wsa_data.wVersion) != 2)) {
+ WSACleanup ();
+ return FALSE;
+ }
+#else
+# ifdef SIGPIPE
+ signal (SIGPIPE, SIG_IGN);
+# endif
+#endif
+ return TRUE;
+}
+
+void
+p_socket_close_once (void)
+{
+#ifdef P_OS_WIN
+ WSACleanup ();
+#endif
+}
+
+P_LIB_API PSocket *
+p_socket_new_from_fd (pint fd,
+ PError **error)
+{
+ PSocket *ret;
+#if !defined (P_OS_WIN) && defined (SO_NOSIGPIPE)
+ pint flags;
+#endif
+
+ if (P_UNLIKELY (fd < 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Unable to create socket from bad fd");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocket))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for socket");
+ return NULL;
+ }
+
+ ret->fd = fd;
+
+ if (P_UNLIKELY (pp_socket_set_details_from_fd (ret, error) == FALSE)) {
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pp_socket_set_fd_blocking (ret->fd, FALSE, error) == FALSE)) {
+ p_free (ret);
+ return NULL;
+ }
+
+#if !defined (P_OS_WIN) && defined (SO_NOSIGPIPE)
+ flags = 1;
+
+ if (setsockopt (ret->fd, SOL_SOCKET, SO_NOSIGPIPE, &flags, sizeof (flags)) < 0)
+ P_WARNING ("PSocket::p_socket_new_from_fd: setsockopt() with SO_NOSIGPIPE failed");
+#endif
+
+ p_socket_set_listen_backlog (ret, P_SOCKET_DEFAULT_BACKLOG);
+
+ ret->timeout = 0;
+ ret->blocking = TRUE;
+
+#ifdef P_OS_SCO
+ if (P_UNLIKELY ((ret->timer = p_time_profiler_new ()) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for internal timer");
+ p_free (ret);
+ return NULL;
+ }
+#endif
+
+#ifdef P_OS_WIN
+ if (P_UNLIKELY ((ret->events = WSACreateEvent ()) == WSA_INVALID_EVENT)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ (pint) p_error_get_last_net (),
+ "Failed to call WSACreateEvent() on socket");
+ p_free (ret);
+ return NULL;
+ }
+#endif
+
+ return ret;
+}
+
+P_LIB_API PSocket *
+p_socket_new (PSocketFamily family,
+ PSocketType type,
+ PSocketProtocol protocol,
+ PError **error)
+{
+ PSocket *ret;
+ pint native_type, fd;
+#ifndef P_OS_WIN
+ pint flags;
+#endif
+
+ if (P_UNLIKELY (family == P_SOCKET_FAMILY_UNKNOWN ||
+ type == P_SOCKET_TYPE_UNKNOWN ||
+ protocol == P_SOCKET_PROTOCOL_UNKNOWN)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input socket family, type or protocol");
+ return NULL;
+ }
+
+ switch (type) {
+ case P_SOCKET_TYPE_STREAM:
+ native_type = SOCK_STREAM;
+ break;
+
+ case P_SOCKET_TYPE_DATAGRAM:
+ native_type = SOCK_DGRAM;
+ break;
+
+#ifdef SOCK_SEQPACKET
+ case P_SOCKET_TYPE_SEQPACKET:
+ native_type = SOCK_SEQPACKET;
+ break;
+#endif
+
+ default:
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Unable to create socket with unknown family");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocket))) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for socket");
+ return NULL;
+ }
+
+#ifdef P_OS_SCO
+ if (P_UNLIKELY ((ret->timer = p_time_profiler_new ()) == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_NO_RESOURCES,
+ 0,
+ "Failed to allocate memory for internal timer");
+ p_free (ret);
+ return NULL;
+ }
+#endif
+
+#ifdef SOCK_CLOEXEC
+ native_type |= SOCK_CLOEXEC;
+#endif
+ if (P_UNLIKELY ((fd = (pint) socket (family, native_type, protocol)) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call socket() to create socket");
+#ifdef P_OS_SCO
+ p_time_profiler_free (ret->timer);
+#endif
+ p_free (ret);
+ return NULL;
+ }
+
+#ifndef P_OS_WIN
+ flags = fcntl (fd, F_GETFD, 0);
+
+ if (P_LIKELY (flags != -1 && (flags & FD_CLOEXEC) == 0)) {
+ flags |= FD_CLOEXEC;
+
+ if (P_UNLIKELY (fcntl (fd, F_SETFD, flags) < 0))
+ P_WARNING ("PSocket::p_socket_new: fcntl() with FD_CLOEXEC failed");
+ }
+#endif
+
+ ret->fd = fd;
+
+#ifdef P_OS_WIN
+ ret->events = WSA_INVALID_EVENT;
+#endif
+
+ if (P_UNLIKELY (pp_socket_set_fd_blocking (ret->fd, FALSE, error) == FALSE)) {
+ p_socket_free (ret);
+ return NULL;
+ }
+
+#if !defined (P_OS_WIN) && defined (SO_NOSIGPIPE)
+ flags = 1;
+
+ if (setsockopt (ret->fd, SOL_SOCKET, SO_NOSIGPIPE, &flags, sizeof (flags)) < 0)
+ P_WARNING ("PSocket::p_socket_new: setsockopt() with SO_NOSIGPIPE failed");
+#endif
+
+ ret->timeout = 0;
+ ret->blocking = TRUE;
+ ret->family = family;
+ ret->protocol = protocol;
+ ret->type = type;
+
+ p_socket_set_listen_backlog (ret, P_SOCKET_DEFAULT_BACKLOG);
+
+#ifdef P_OS_WIN
+ if (P_UNLIKELY ((ret->events = WSACreateEvent ()) == WSA_INVALID_EVENT)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ (pint) p_error_get_last_net (),
+ "Failed to call WSACreateEvent() on socket");
+ p_socket_free (ret);
+ return NULL;
+ }
+#endif
+
+ return ret;
+}
+
+P_LIB_API pint
+p_socket_get_fd (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return -1;
+
+ return socket->fd;
+}
+
+P_LIB_API PSocketFamily
+p_socket_get_family (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return P_SOCKET_FAMILY_UNKNOWN;
+
+ return socket->family;
+}
+
+P_LIB_API PSocketType
+p_socket_get_type (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return P_SOCKET_TYPE_UNKNOWN;
+
+ return socket->type;
+}
+
+P_LIB_API PSocketProtocol
+p_socket_get_protocol (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return P_SOCKET_PROTOCOL_UNKNOWN;
+
+ return socket->protocol;
+}
+
+P_LIB_API pboolean
+p_socket_get_keepalive (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return FALSE;
+
+ return socket->keepalive;
+}
+
+P_LIB_API pboolean
+p_socket_get_blocking (PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return FALSE;
+
+ return socket->blocking;
+}
+
+P_LIB_API int
+p_socket_get_listen_backlog (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return -1;
+
+ return socket->listen_backlog;
+}
+
+P_LIB_API pint
+p_socket_get_timeout (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return -1;
+
+ return socket->timeout;
+}
+
+P_LIB_API PSocketAddress *
+p_socket_get_local_address (const PSocket *socket,
+ PError **error)
+{
+ struct sockaddr_storage buffer;
+ socklen_t len;
+ PSocketAddress *ret;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ len = sizeof (buffer);
+
+ if (P_UNLIKELY (getsockname (socket->fd, (struct sockaddr *) &buffer, &len) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getsockname() to get local socket address");
+ return NULL;
+ }
+
+ ret = p_socket_address_new_from_native (&buffer, (psize) len);
+
+ if (P_UNLIKELY (ret == NULL))
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to create socket address from native structure");
+
+ return ret;
+}
+
+P_LIB_API PSocketAddress *
+p_socket_get_remote_address (const PSocket *socket,
+ PError **error)
+{
+ struct sockaddr_storage buffer;
+ socklen_t len;
+ PSocketAddress *ret;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ len = sizeof (buffer);
+
+ if (P_UNLIKELY (getpeername (socket->fd, (struct sockaddr *) &buffer, &len) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getpeername() to get remote socket address");
+ return NULL;
+ }
+
+#ifdef P_OS_SYLLABLE
+ /* Syllable has a bug with a wrong byte order for a TCP port,
+ * as it only supports IPv4 we can easily fix it here. */
+ ((struct sockaddr_in *) &buffer)->sin_port =
+ p_htons (((struct sockaddr_in *) &buffer)->sin_port);
+#endif
+
+ ret = p_socket_address_new_from_native (&buffer, (psize) len);
+
+ if (P_UNLIKELY (ret == NULL))
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to create socket address from native structure");
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_socket_is_connected (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return FALSE;
+
+ return socket->connected;
+}
+
+P_LIB_API pboolean
+p_socket_is_closed (const PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return TRUE;
+
+ return socket->closed;
+}
+
+P_LIB_API pboolean
+p_socket_check_connect_result (PSocket *socket,
+ PError **error)
+{
+ socklen_t optlen;
+ pint val;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ optlen = sizeof (val);
+
+ if (P_UNLIKELY (getsockopt (socket->fd, SOL_SOCKET, SO_ERROR, (ppointer) &val, &optlen) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call getsockopt() to get connection status");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (val != 0))
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (val),
+ val,
+ "Error in socket layer");
+
+ socket->connected = (val == 0);
+
+ return (val == 0);
+}
+
+P_LIB_API void
+p_socket_set_keepalive (PSocket *socket,
+ pboolean keepalive)
+{
+#ifdef P_OS_WIN
+ pchar value;
+#else
+ pint value;
+#endif
+
+ if (P_UNLIKELY (socket == NULL))
+ return;
+
+ if (socket->keepalive == (puint) !!keepalive)
+ return;
+
+#ifdef P_OS_WIN
+ value = !! (pchar) keepalive;
+#else
+ value = !! (pint) keepalive;
+#endif
+ if (setsockopt (socket->fd, SOL_SOCKET, SO_KEEPALIVE, &value, sizeof (value)) < 0) {
+ P_WARNING ("PSocket::p_socket_set_keepalive: setsockopt() with SO_KEEPALIVE failed");
+ return;
+ }
+
+ socket->keepalive = !! (pint) keepalive;
+}
+
+P_LIB_API void
+p_socket_set_blocking (PSocket *socket,
+ pboolean blocking)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return;
+
+ socket->blocking = !! blocking;
+}
+
+P_LIB_API void
+p_socket_set_listen_backlog (PSocket *socket,
+ pint backlog)
+{
+ if (P_UNLIKELY (socket == NULL || socket->listening))
+ return;
+
+ socket->listen_backlog = backlog;
+}
+
+P_LIB_API void
+p_socket_set_timeout (PSocket *socket,
+ pint timeout)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return;
+
+ if (timeout < 0)
+ timeout = 0;
+
+ socket->timeout = timeout;
+}
+
+P_LIB_API pboolean
+p_socket_bind (const PSocket *socket,
+ PSocketAddress *address,
+ pboolean allow_reuse,
+ PError **error)
+{
+ struct sockaddr_storage addr;
+
+#ifdef SO_REUSEPORT
+ pboolean reuse_port;
+#endif
+
+#ifdef P_OS_WIN
+ pchar value;
+#else
+ pint value;
+#endif
+
+ if (P_UNLIKELY (socket == NULL || address == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ /* Windows allows to reuse the same address even for an active TCP
+ * connection, that's why on Windows we should use SO_REUSEADDR only
+ * for UDP sockets, UNIX doesn't have such behavior
+ *
+ * Ignore errors here, the only likely error is "not supported", and
+ * this is a "best effort" thing mainly */
+
+#ifdef P_OS_WIN
+ value = !! (pchar) (allow_reuse && (socket->type == P_SOCKET_TYPE_DATAGRAM));
+#else
+ value = !! (pint) allow_reuse;
+#endif
+
+ if (setsockopt (socket->fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof (value)) < 0)
+ P_WARNING ("PSocket::p_socket_bind: setsockopt() with SO_REUSEADDR failed");
+
+#ifdef SO_REUSEPORT
+ reuse_port = allow_reuse && (socket->type == P_SOCKET_TYPE_DATAGRAM);
+
+# ifdef P_OS_WIN
+ value = !! (pchar) reuse_port;
+# else
+ value = !! (pint) reuse_port;
+# endif
+
+ if (setsockopt (socket->fd, SOL_SOCKET, SO_REUSEPORT, &value, sizeof (value)) < 0)
+ P_WARNING ("PSocket::p_socket_bind: setsockopt() with SO_REUSEPORT failed");
+#endif
+
+ if (P_UNLIKELY (p_socket_address_to_native (address, &addr, sizeof (addr)) == FALSE)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to convert socket address to native structure");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (bind (socket->fd,
+ (struct sockaddr *) &addr,
+ (socklen_t) p_socket_address_get_native_size (address)) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call bind() on socket");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_socket_connect (PSocket *socket,
+ PSocketAddress *address,
+ PError **error)
+{
+ struct sockaddr_storage buffer;
+ pint err_code;
+ pint conn_result;
+ PErrorIO sock_err;
+
+ if (P_UNLIKELY (socket == NULL || address == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ if (P_UNLIKELY (p_socket_address_to_native (address, &buffer, sizeof (buffer)) == FALSE)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to convert socket address to native structure");
+ return FALSE;
+ }
+
+#if !defined (P_OS_WIN) && defined (EINTR)
+ for (;;) {
+ conn_result = connect (socket->fd, (struct sockaddr *) &buffer,
+ (socklen_t) p_socket_address_get_native_size (address));
+
+ if (P_LIKELY (conn_result == 0))
+ break;
+
+ err_code = p_error_get_last_net ();
+
+ if (err_code == EINTR)
+ continue;
+ else
+ break;
+ }
+#else
+ conn_result = connect (socket->fd, (struct sockaddr *) &buffer,
+ (pint) p_socket_address_get_native_size (address));
+
+ if (conn_result != 0)
+ err_code = p_error_get_last_net ();
+#endif
+
+ if (conn_result == 0) {
+ socket->connected = TRUE;
+ return TRUE;
+ }
+
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (P_LIKELY (sock_err == P_ERROR_IO_WOULD_BLOCK || sock_err == P_ERROR_IO_IN_PROGRESS)) {
+ if (socket->blocking) {
+ if (p_socket_io_condition_wait (socket,
+ P_SOCKET_IO_CONDITION_POLLOUT,
+ error) == TRUE &&
+ p_socket_check_connect_result (socket, error) == TRUE) {
+ socket->connected = TRUE;
+ return TRUE;
+ }
+ } else
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Couldn't block non-blocking socket");
+ } else
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call connect() on socket");
+
+ return FALSE;
+}
+
+P_LIB_API pboolean
+p_socket_listen (PSocket *socket,
+ PError **error)
+{
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ if (P_UNLIKELY (listen (socket->fd, socket->listen_backlog) < 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call listen() on socket");
+ return FALSE;
+ }
+
+ socket->listening = TRUE;
+ return TRUE;
+}
+
+P_LIB_API PSocket *
+p_socket_accept (const PSocket *socket,
+ PError **error)
+{
+ PSocket *ret;
+ PErrorIO sock_err;
+ pint res;
+ pint err_code;
+#ifndef P_OS_WIN
+ pint flags;
+#endif
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return NULL;
+
+ for (;;) {
+ if (socket->blocking &&
+ p_socket_io_condition_wait (socket,
+ P_SOCKET_IO_CONDITION_POLLIN,
+ error) == FALSE)
+ return NULL;
+
+ if ((res = (pint) accept (socket->fd, NULL, 0)) < 0) {
+ err_code = p_error_get_last_net ();
+#if !defined (P_OS_WIN) && defined (EINTR)
+ if (p_error_get_last_net () == EINTR)
+ continue;
+#endif
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (socket->blocking && sock_err == P_ERROR_IO_WOULD_BLOCK)
+ continue;
+
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call accept() on socket");
+
+ return NULL;
+ }
+
+ break;
+ }
+
+#ifdef P_OS_WIN
+ /* The socket inherits the accepting sockets event mask and even object,
+ * we need to remove that */
+ WSAEventSelect (res, NULL, 0);
+#else
+ flags = fcntl (res, F_GETFD, 0);
+
+ if (P_LIKELY (flags != -1 && (flags & FD_CLOEXEC) == 0)) {
+ flags |= FD_CLOEXEC;
+
+ if (P_UNLIKELY (fcntl (res, F_SETFD, flags) < 0))
+ P_WARNING ("PSocket::p_socket_accept: fcntl() with FD_CLOEXEC failed");
+ }
+#endif
+
+ if (P_UNLIKELY ((ret = p_socket_new_from_fd (res, error)) == NULL)) {
+ if (P_UNLIKELY (p_sys_close (res) != 0))
+ P_WARNING ("PSocket::p_socket_accept: p_sys_close() failed");
+ } else
+ ret->protocol = socket->protocol;
+
+ return ret;
+}
+
+P_LIB_API pssize
+p_socket_receive (const PSocket *socket,
+ pchar *buffer,
+ psize buflen,
+ PError **error)
+{
+ PErrorIO sock_err;
+ pssize ret;
+ pint err_code;
+
+ if (P_UNLIKELY (socket == NULL || buffer == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return -1;
+
+ for (;;) {
+ if (socket->blocking &&
+ p_socket_io_condition_wait (socket,
+ P_SOCKET_IO_CONDITION_POLLIN,
+ error) == FALSE)
+ return -1;
+
+ if ((ret = recv (socket->fd, buffer, (socklen_t) buflen, 0)) < 0) {
+ err_code = p_error_get_last_net ();
+
+#if !defined (P_OS_WIN) && defined (EINTR)
+ if (err_code == EINTR)
+ continue;
+#endif
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (socket->blocking && sock_err == P_ERROR_IO_WOULD_BLOCK)
+ continue;
+
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call recv() on socket");
+
+ return -1;
+ }
+
+ break;
+ }
+
+ return ret;
+}
+
+P_LIB_API pssize
+p_socket_receive_from (const PSocket *socket,
+ PSocketAddress **address,
+ pchar *buffer,
+ psize buflen,
+ PError **error)
+{
+ PErrorIO sock_err;
+ struct sockaddr_storage sa;
+ socklen_t optlen;
+ pssize ret;
+ pint err_code;
+
+ if (P_UNLIKELY (socket == NULL || buffer == NULL || buflen == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return -1;
+
+ optlen = sizeof (sa);
+
+ for (;;) {
+ if (socket->blocking &&
+ p_socket_io_condition_wait (socket,
+ P_SOCKET_IO_CONDITION_POLLIN,
+ error) == FALSE)
+ return -1;
+
+ if ((ret = recvfrom (socket->fd,
+ buffer,
+ (socklen_t) buflen,
+ 0,
+ (struct sockaddr *) &sa,
+ &optlen)) < 0) {
+ err_code = p_error_get_last_net ();
+
+#if !defined (P_OS_WIN) && defined (EINTR)
+ if (err_code == EINTR)
+ continue;
+#endif
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (socket->blocking && sock_err == P_ERROR_IO_WOULD_BLOCK)
+ continue;
+
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call recvfrom() on socket");
+
+ return -1;
+ }
+
+ break;
+ }
+
+ if (address != NULL)
+ *address = p_socket_address_new_from_native (&sa, optlen);
+
+ return ret;
+}
+
+P_LIB_API pssize
+p_socket_send (const PSocket *socket,
+ const pchar *buffer,
+ psize buflen,
+ PError **error)
+{
+ PErrorIO sock_err;
+ pssize ret;
+ pint err_code;
+
+ if (P_UNLIKELY (socket == NULL || buffer == NULL || buflen == 0)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return -1;
+
+ for (;;) {
+ if (socket->blocking &&
+ p_socket_io_condition_wait (socket,
+ P_SOCKET_IO_CONDITION_POLLOUT,
+ error) == FALSE)
+ return -1;
+
+ if ((ret = send (socket->fd,
+ buffer,
+ (socklen_t) buflen,
+ P_SOCKET_DEFAULT_SEND_FLAGS)) < 0) {
+ err_code = p_error_get_last_net ();
+
+#if !defined (P_OS_WIN) && defined (EINTR)
+ if (err_code == EINTR)
+ continue;
+#endif
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (socket->blocking && sock_err == P_ERROR_IO_WOULD_BLOCK)
+ continue;
+
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call send() on socket");
+
+ return -1;
+ }
+
+ break;
+ }
+
+ return ret;
+}
+
+P_LIB_API pssize
+p_socket_send_to (const PSocket *socket,
+ PSocketAddress *address,
+ const pchar *buffer,
+ psize buflen,
+ PError **error)
+{
+ PErrorIO sock_err;
+ struct sockaddr_storage sa;
+ socklen_t optlen;
+ pssize ret;
+ pint err_code;
+
+ if (!socket || !address || !buffer) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return -1;
+ }
+
+ if (!pp_socket_check (socket, error))
+ return -1;
+
+ if (!p_socket_address_to_native (address, &sa, sizeof (sa))) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_FAILED,
+ 0,
+ "Failed to convert socket address to native structure");
+ return -1;
+ }
+
+ optlen = (socklen_t) p_socket_address_get_native_size (address);
+
+ for (;;) {
+ if (socket->blocking &&
+ p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, error) == FALSE)
+ return -1;
+
+ if ((ret = sendto (socket->fd,
+ buffer,
+ (socklen_t) buflen,
+ 0,
+ (struct sockaddr *) &sa,
+ optlen)) < 0) {
+ err_code = p_error_get_last_net ();
+
+#if !defined (P_OS_WIN) && defined (EINTR)
+ if (err_code == EINTR)
+ continue;
+#endif
+ sock_err = p_error_get_io_from_system (err_code);
+
+ if (socket->blocking && sock_err == P_ERROR_IO_WOULD_BLOCK)
+ continue;
+
+ p_error_set_error_p (error,
+ (pint) sock_err,
+ err_code,
+ "Failed to call sendto() on socket");
+
+ return -1;
+ }
+
+ break;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_socket_close (PSocket *socket,
+ PError **error)
+{
+ pint err_code;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (socket->closed)
+ return TRUE;
+
+ if (P_LIKELY (p_sys_close (socket->fd) == 0)) {
+ socket->connected = FALSE;
+ socket->closed = TRUE;
+ socket->listening = FALSE;
+ socket->fd = -1;
+
+ return TRUE;
+ } else {
+ err_code = p_error_get_last_net ();
+
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (err_code),
+ err_code,
+ "Failed to close socket");
+
+ return FALSE;
+ }
+}
+
+P_LIB_API pboolean
+p_socket_shutdown (PSocket *socket,
+ pboolean shutdown_read,
+ pboolean shutdown_write,
+ PError **error)
+{
+ pint how;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ if (P_UNLIKELY (shutdown_read == FALSE && shutdown_write == FALSE))
+ return TRUE;
+
+#ifndef P_OS_WIN
+ if (shutdown_read == TRUE && shutdown_write == TRUE)
+ how = SHUT_RDWR;
+ else if (shutdown_read == TRUE)
+ how = SHUT_RD;
+ else
+ how = SHUT_WR;
+#else
+ if (shutdown_read == TRUE && shutdown_write == TRUE)
+ how = SD_BOTH;
+ else if (shutdown_read == TRUE)
+ how = SD_RECEIVE;
+ else
+ how = SD_SEND;
+#endif
+
+ if (P_UNLIKELY (shutdown (socket->fd, how) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call shutdown() on socket");
+ return FALSE;
+ }
+
+ if (shutdown_read == TRUE && shutdown_write == TRUE)
+ socket->connected = FALSE;
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_socket_free (PSocket *socket)
+{
+ if (P_UNLIKELY (socket == NULL))
+ return;
+
+#ifdef P_OS_WIN
+ if (P_LIKELY (socket->events != WSA_INVALID_EVENT))
+ WSACloseEvent (socket->events);
+#endif
+
+ p_socket_close (socket, NULL);
+
+#ifdef P_OS_SCO
+ if (P_LIKELY (socket->timer != NULL))
+ p_time_profiler_free (socket->timer);
+#endif
+
+ p_free (socket);
+}
+
+P_LIB_API pboolean
+p_socket_set_buffer_size (const PSocket *socket,
+ PSocketDirection dir,
+ psize size,
+ PError **error)
+{
+ pint optname;
+ pint optval;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ optname = (dir == P_SOCKET_DIRECTION_RCV) ? SO_RCVBUF : SO_SNDBUF;
+ optval = (pint) size;
+
+ if (P_UNLIKELY (setsockopt (socket->fd,
+ SOL_SOCKET,
+ optname,
+ (pconstpointer) &optval,
+ sizeof (optval)) != 0)) {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call setsockopt() on socket to set buffer size");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_socket_io_condition_wait (const PSocket *socket,
+ PSocketIOCondition condition,
+ PError **error)
+{
+#if defined (P_OS_WIN)
+ long network_events;
+ pint evret;
+ pint timeout;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ timeout = socket->timeout > 0 ? socket->timeout : WSA_INFINITE;
+
+ if (condition == P_SOCKET_IO_CONDITION_POLLIN)
+ network_events = FD_READ | FD_ACCEPT;
+ else
+ network_events = FD_WRITE | FD_CONNECT;
+
+ WSAResetEvent (socket->events);
+ WSAEventSelect (socket->fd, socket->events, network_events);
+
+ evret = WSAWaitForMultipleEvents (1, (const HANDLE *) &socket->events, TRUE, timeout, FALSE);
+
+ if (evret == WSA_WAIT_EVENT_0)
+ return TRUE;
+ else if (evret == WSA_WAIT_TIMEOUT) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_TIMED_OUT,
+ (pint) p_error_get_last_net (),
+ "Timed out while waiting socket condition");
+ return FALSE;
+ } else {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call WSAWaitForMultipleEvents() on socket");
+ return FALSE;
+ }
+#elif defined (P_SOCKET_USE_POLL)
+ struct pollfd pfd;
+ pint evret;
+ pint timeout;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ timeout = socket->timeout > 0 ? socket->timeout : -1;
+
+ pfd.fd = socket->fd;
+ pfd.revents = 0;
+
+ if (condition == P_SOCKET_IO_CONDITION_POLLIN)
+ pfd.events = POLLIN;
+ else
+ pfd.events = POLLOUT;
+
+# ifdef P_OS_SCO
+ p_time_profiler_reset (socket->timer);
+# endif
+
+ while (TRUE) {
+ evret = poll (&pfd, 1, timeout);
+
+# ifdef EINTR
+ if (evret == -1 && p_error_get_last_net () == EINTR) {
+# ifdef P_OS_SCO
+ if (timeout < 0 ||
+ (p_time_profiler_elapsed_usecs (socket->timer) / 1000) < (puint64) timeout)
+ continue;
+ else
+ evret = 0;
+# else
+ continue;
+# endif
+ }
+# endif
+
+ if (evret == 1)
+ return TRUE;
+ else if (evret == 0) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_TIMED_OUT,
+ (pint) p_error_get_last_net (),
+ "Timed out while waiting socket condition");
+ return FALSE;
+ } else {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call poll() on socket");
+ return FALSE;
+ }
+ }
+#else
+ fd_set fds;
+ struct timeval tv;
+ struct timeval * ptv;
+ pint evret;
+
+ if (P_UNLIKELY (socket == NULL)) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_INVALID_ARGUMENT,
+ 0,
+ "Invalid input argument");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_socket_check (socket, error) == FALSE))
+ return FALSE;
+
+ if (socket->timeout > 0)
+ ptv = &tv;
+ else
+ ptv = NULL;
+
+ while (TRUE) {
+ FD_ZERO (&fds);
+ FD_SET (socket->fd, &fds);
+
+ if (socket->timeout > 0) {
+ tv.tv_sec = socket->timeout / 1000;
+ tv.tv_usec = (socket->timeout % 1000) * 1000;
+ }
+
+ if (condition == P_SOCKET_IO_CONDITION_POLLIN)
+ evret = select (socket->fd + 1, &fds, NULL, NULL, ptv);
+ else
+ evret = select (socket->fd + 1, NULL, &fds, NULL, ptv);
+
+#ifdef EINTR
+ if (evret == -1 && p_error_get_last_net () == EINTR)
+ continue;
+#endif
+
+ if (evret == 1)
+ return TRUE;
+ else if (evret == 0) {
+ p_error_set_error_p (error,
+ (pint) P_ERROR_IO_TIMED_OUT,
+ (pint) p_error_get_last_net (),
+ "Timed out while waiting socket condition");
+ return FALSE;
+ } else {
+ p_error_set_error_p (error,
+ (pint) p_error_get_io_from_system (p_error_get_last_net ()),
+ (pint) p_error_get_last_net (),
+ "Failed to call select() on socket");
+ return FALSE;
+ }
+ }
+#endif
+}
diff --git a/3rdparty/plibsys/src/psocket.h b/3rdparty/plibsys/src/psocket.h
new file mode 100644
index 0000000..989e707
--- /dev/null
+++ b/3rdparty/plibsys/src/psocket.h
@@ -0,0 +1,779 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file psocket.h
+ * @brief Socket implementation
+ * @author Alexander Saprykin
+ *
+ * A socket is a communication primitive usually working over a network. You can
+ * send data to someone's socket by its address and receive data as well through
+ * the same socket. This is one of the most popular and standardizated way for
+ * network communication supported by vast majority of all the modern operating
+ * systems. It also hides all the details of underlying networking protocols and
+ * other layers, providing a unified and transparent approach for communication.
+ *
+ * There are two kinds of socket:
+ * - connection oriented (or stream sockets, i.e. TCP);
+ * - connection-less (or datagram sockets, i.e. UDP).
+ *
+ * Connection oriented sockets work with data in a stream, connection-less
+ * sockets work with data using independent packets (datagrams). The former
+ * guarantees delivery, while the latter doesn't (actually some connection-less
+ * protocols provide delivery quarantee, i.e. SCTP).
+ *
+ * #PSocket supports INET and INET6 address families which specify network
+ * communication addresses used by created sockets: IPv4 and IPv6,
+ * correspondingly. INET6 family is not supported on all platforms, refer to
+ * documentation for a particular target platform.
+ *
+ * #PSocket supports different underlying data transfer protocols: TCP, UDP and
+ * others. Note that not all protocols can be used with any socket type, i.e.
+ * you can use the TCP protocol with a stream socket, but you can't use the UDP
+ * protocol with the stream socket. You can specify #P_SOCKET_PROTOCOL_DEFAULT
+ * protocol when creating a socket and appropriate the best matching socket type
+ * will be selected.
+ *
+ * In a common socket communication case server and client sides are involved.
+ * Depending on whether sockets are connection oriented, there are slightly
+ * different action sequences for data exchanging.
+ *
+ * For connection oriented sockets the server side acts as following:
+ * - creates a socket using p_socket_new();
+ * - binds the socket to a particular local address using p_socket_bind();
+ * - starts to listen incoming connections using p_socket_listen();
+ * - takes an incoming connection from the internal queue using
+ * p_socket_accept().
+ *
+ * The client side acts as following:
+ * - creates a socket using p_socket_new();
+ * - binds the socket to a particular local address using p_socket_bind();
+ * - connects to the server using p_socket_connect().
+ *
+ * After the connection was successfully established, both the sides can send
+ * and receive data from each other using p_socket_send() and
+ * p_socket_receive(). Binding of the client socket is actually optional.
+ *
+ * When using connection-less sockets, all is a bit simpler. There is no server
+ * side or client side - anyone can send and receive data without establishing a
+ * connection. Just create a socket, bind it to a local address and send/receive
+ * data using p_socket_send_to() and p_socket_receive(). You can also call
+ * p_socket_connect() on a connection-less socket to prevent passing the target
+ * address each time when sending data and then use p_socket_send() instead of
+ * p_socket_send_to(). This time binding is required.
+ *
+ * #PSocket can operate in blocking and non-blocking (async) modes. By default
+ * it is in the blocking mode. When using #PSocket in the blocking mode each
+ * non-immediate call on it will block a caller thread until an I/O operation
+ * will be completed. For example, the p_socket_accept() call can wait for an
+ * incoming connection for some time, and calling it on a blocking socket will
+ * prevent the caller thread from further execution until it receives a new
+ * incoming connection. In the non-blocking mode any call will return
+ * immediately and you must check its result. You can set the socket mode using
+ * p_socket_set_blocking().
+ *
+ * #PSocket always puts a socket descriptor (or SOCKET handle on Windows) into
+ * the non-blocking mode and emulates the blocking mode if required. If you need
+ * to perform some hacks and need blocking behavior from the descriptor for some
+ * reason, use p_socket_get_fd() to get an internal socket descriptor (SOCKET
+ * handle on Windows).
+ *
+ * The close-on-exec flag is always set on the socket desciptor. Use
+ * p_socket_get_fd() to overwrite this behavior.
+ *
+ * #PSocket ignores the SIGPIPE signal on UNIX systems if possible. Take it into
+ * account if you want to handle this signal.
+ *
+ * Note that before using the #PSocket API you must call p_libsys_init() in
+ * order to initialize system resources (on UNIX this will do nothing, but on
+ * Windows this routine is required). Usually this routine should be called on a
+ * program's start.
+ *
+ * Here is an example of #PSocket usage:
+ * @code
+ * PSocketAddress *addr;
+ * PSocket *sock;
+ *
+ * p_libsys_init ();
+ * ...
+ * if ((addr = p_socket_address_new ("127.0.0.1", 5432)) == NULL) {
+ * ...
+ * }
+ *
+ * if ((sock = p_socket_new (P_SOCKET_FAMILY_INET,
+ * P_SOCKET_TYPE_DATAGRAM,
+ * P_SOCKET_PROTOCOL_UDP)) == NULL) {
+ * p_socket_address_free (addr);
+ * ...
+ * }
+ *
+ * if (!p_socket_bind (sock, addr, FALSE)) {
+ * p_socket_address_free(addr);
+ * p_socket_free(sock);
+ * ...
+ * }
+ *
+ * ...
+ * p_socket_address_free (addr);
+ * p_socket_close (sock);
+ * p_socket_free (sock);
+ * p_libsys_shutdown ();
+ * @endcode
+ * Here a UDP socket was created, bound to the localhost address and the port
+ * @a 5432. Do not forget to close the socket and free memory after its usage.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSOCKET_H
+#define PLIBSYS_HEADER_PSOCKET_H
+
+#include <pmacros.h>
+#include <psocketaddress.h>
+#include <perror.h>
+
+P_BEGIN_DECLS
+
+/** Socket protocols specified by the IANA. */
+typedef enum PSocketProtocol_ {
+ P_SOCKET_PROTOCOL_UNKNOWN = -1, /**< Unknown protocol. */
+ P_SOCKET_PROTOCOL_DEFAULT = 0, /**< Default protocol. */
+ P_SOCKET_PROTOCOL_TCP = 6, /**< TCP protocol. */
+ P_SOCKET_PROTOCOL_UDP = 17, /**< UDP protocol. */
+ P_SOCKET_PROTOCOL_SCTP = 132 /**< SCTP protocol. */
+} PSocketProtocol;
+
+/** Socket types. */
+typedef enum PSocketType_ {
+ P_SOCKET_TYPE_UNKNOWN = 0, /**< Unknown type. */
+ P_SOCKET_TYPE_STREAM = 1, /**< Connection oritented, reliable, stream of bytes (i.e. TCP). */
+ P_SOCKET_TYPE_DATAGRAM = 2, /**< Connection-less, unreliable, datagram passing (i.e. UDP). */
+ P_SOCKET_TYPE_SEQPACKET = 3 /**< Connection-less, reliable, datagram passing (i.e. SCTP). */
+} PSocketType;
+
+/** Socket direction for data operations. */
+typedef enum PSocketDirection_ {
+ P_SOCKET_DIRECTION_SND = 0, /**< Send direction. */
+ P_SOCKET_DIRECTION_RCV = 1 /**< Receive direction. */
+} PSocketDirection;
+
+/** Socket IO waiting (polling) conditions. */
+typedef enum PSocketIOCondition_ {
+ P_SOCKET_IO_CONDITION_POLLIN = 1, /**< Ready to read. */
+ P_SOCKET_IO_CONDITION_POLLOUT = 2 /**< Ready to write. */
+} PSocketIOCondition;
+
+/** Socket opaque structure. */
+typedef struct PSocket_ PSocket;
+
+/**
+ * @brief Creates a new #PSocket object from a file descriptor.
+ * @param fd File descriptor to create the socket from.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to #PSocket in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @sa p_socket_new(), p_socket_get_fd()
+ *
+ * The given file descriptor @a fd will be put in a non-blocking mode. #PSocket
+ * will emulate a blocking mode if required.
+ *
+ * If the socket was not bound yet then on some systems (i.e. Windows) call may
+ * fail to get a socket family from the descriptor thus failing to construct the
+ * #PSocket object.
+ */
+P_LIB_API PSocket * p_socket_new_from_fd (pint fd,
+ PError **error);
+
+/**
+ * @brief Creates a new #PSocket object.
+ * @param family Socket family.
+ * @param type Socket type.
+ * @param protocol Socket data transfer protocol.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Pointer to #PSocket in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note If all the given parameters are not compatible with each other, then
+ * the function will fail. Use #P_SOCKET_PROTOCOL_DEFAULT to automatically
+ * match the best protocol for a particular @a type.
+ * @sa #PSocketFamily, #PSocketType, #PSocketProtocol, p_socket_new_from_fd()
+ *
+ * The @a protocol is passed directly to the operating system socket() call,
+ * #PSocketProtocol has the same values as the system definitions. You can pass
+ * any existing protocol value to this call if you know it exactly.
+ */
+P_LIB_API PSocket * p_socket_new (PSocketFamily family,
+ PSocketType type,
+ PSocketProtocol protocol,
+ PError **error);
+
+/**
+ * @brief Gets an underlying file descriptor of a @a socket.
+ * @param socket #PSocket to get the file descriptor for.
+ * @return File descriptor in case of success, -1 otherwise.
+ * @since 0.0.1
+ * @sa p_socket_new_from_fd()
+ */
+P_LIB_API pint p_socket_get_fd (const PSocket *socket);
+
+/**
+ * @brief Gets a @a socket address family.
+ * @param socket #PSocket to get the address family for.
+ * @return #PSocketFamily in case of success, #P_SOCKET_FAMILY_UNKNOWN
+ * otherwise.
+ * @since 0.0.1
+ * @sa #PSocketFamily, p_socket_new()
+ *
+ * The socket address family specifies address space which will be used to
+ * communicate with other sockets. For now, the INET and INET6 families are
+ * supported. The INET6 family is available only if the operating system
+ * supports it.
+ */
+P_LIB_API PSocketFamily p_socket_get_family (const PSocket *socket);
+
+/**
+ * @brief Gets a @a socket type.
+ * @param socket #PSocket to get the type for.
+ * @return #PSocketType in case of success, #P_SOCKET_TYPE_UNKNOWN otherwise.
+ * @since 0.0.1
+ * @sa #PSocketType, p_socket_new()
+ */
+P_LIB_API PSocketType p_socket_get_type (const PSocket *socket);
+
+/**
+ * @brief Gets a @a socket data transfer protocol.
+ * @param socket #PSocket to get the data transfer protocol for.
+ * @return #PSocketProtocol in case of success, #P_SOCKET_PROTOCOL_UNKNOWN
+ * otherwise.
+ * @since 0.0.1
+ * @sa #PSocketProtocol, p_socket_new()
+ */
+P_LIB_API PSocketProtocol p_socket_get_protocol (const PSocket *socket);
+
+/**
+ * @brief Checks whether the SO_KEEPALIVE flag is enabled.
+ * @param socket #PSocket to check the SO_KEEPALIVE flag for.
+ * @return TRUE if the SO_KEEPALIVE flag is enabled, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_set_keepalive()
+ *
+ * This option only has effect for connection oriented sockets. After a
+ * connection has been established between two sockets, they periodically send
+ * ping packets to each other to make sure that the connection is alive. A
+ * time interval between alive packets is system dependent and varies from
+ * several minutes to several hours.
+ *
+ * The main usage of this option is to detect dead clients on a server side and
+ * close such the broken sockets to free resources for the actual clients which
+ * may want to connect to the server. Some servers may let clients to be idle
+ * for a long time, so such an option helps to detect died clients faster
+ * without sending them real data. It's some kind of garbage collecting.
+ */
+P_LIB_API pboolean p_socket_get_keepalive (const PSocket *socket);
+
+/**
+ * @brief Checks whether @a socket is used in a blocking mode.
+ * @param socket #PSocket to check the blocking mode for.
+ * @return TRUE if @a socket is in the blocking mode, FALSE otherwise.
+ * @note A blocking socket will wait for an I/O operation to be completed before
+ * returning to the caller function.
+ * @since 0.0.1
+ * @sa p_socket_set_blocking()
+ *
+ * The underlying socket descriptor is always set to the non-blocking mode by
+ * default and #PSocket emulates the blocking mode if required.
+ */
+P_LIB_API pboolean p_socket_get_blocking (PSocket *socket);
+
+/**
+ * @brief Gets a @a socket listen backlog parameter.
+ * @param socket #PSocket to get the listen backlog parameter for.
+ * @return Listen backlog parameter in case of success, -1 otherwise.
+ * @since 0.0.1
+ * @sa p_socket_set_listen_backlog(), p_socket_listen()
+ *
+ * This parameter only has meaning for the connection oriented sockets. The
+ * backlog parameter specifies how much pending connections from other clients
+ * can be stored in the internal (system) queue. If the socket has already the
+ * number of pending connections equal to the backlog parameter, and another
+ * client attempts to connect on that time, it (client) will either be refused
+ * or retransmitted. This behavior is system and protocol dependent.
+ *
+ * Some systems may not allow to set it to high values. By default #PSocket
+ * attempts to set it to 5.
+ */
+P_LIB_API pint p_socket_get_listen_backlog (const PSocket *socket);
+
+/**
+ * @brief Gets a @a socket timeout for blocking I/O operations.
+ * @param socket #PSocket to get the timeout for.
+ * @return Timeout for blocking I/O operations in milliseconds, -1 in case of
+ * fail.
+ * @since 0.0.1
+ * @sa p_socket_set_timeout(), p_socket_io_condition_wait()
+ *
+ * For a blocking socket a timeout value means maximum amount of time for which
+ * a blocking call will wait until a newtwork I/O operation completes. If the
+ * operation is not finished after the timeout, the blocking call returns with
+ * the error set to #P_ERROR_IO_TIMED_OUT.
+ *
+ * For a non-blocking socket the timeout affects only on the
+ * p_socket_io_condition_wait() maximum waiting time.
+ *
+ * Zero timeout means that the operation which requires a time to complete
+ * network I/O will be blocked until the operation finishes or error occurres.
+ */
+P_LIB_API pint p_socket_get_timeout (const PSocket *socket);
+
+/**
+ * @brief Gets a @a socket local (bound) address.
+ * @param socket #PSocket to get the local address for.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return #PSocketAddress with the socket local address in case of success,
+ * NULL otherwise.
+ * @since 0.0.1
+ * @sa p_socket_bind()
+ *
+ * If the @a socket was not bound explicitly with p_socket_bind() or implicitly
+ * with p_socket_connect(), the call will fail.
+ */
+P_LIB_API PSocketAddress * p_socket_get_local_address (const PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Gets a @a socket remote endpoint address.
+ * @param socket #PSocket to get the remote endpoint address for.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return #PSocketAddress with the socket endpoint remote address in case of
+ * success, NULL otherwise.
+ * @since 0.0.1
+ * @sa p_socket_connect()
+ *
+ * If the @a socket was not connected to the endpoint address with
+ * p_socket_connect(), the call will fail.
+ *
+ * @warning On Syllable this call will always return NULL for connection-less
+ * sockets (though connecting is possible).
+ */
+P_LIB_API PSocketAddress * p_socket_get_remote_address (const PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Checks whether a @a socket is connected.
+ * @param socket #PSocket to check a connection for.
+ * @return TRUE if the @a socket is connected, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_connect(), p_socket_check_connect_result()
+ *
+ * This function doesn't check if the socket is still connected, it only checks
+ * whether the p_socket_connect() call was successfully performed on the
+ * @a socket.
+ */
+P_LIB_API pboolean p_socket_is_connected (const PSocket *socket);
+
+/**
+ * @brief Checks whether a @a socket is closed.
+ * @param socket #PSocket to check a closed state.
+ * @return TRUE if the @a socket is closed, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_close(), p_socket_shutdown()
+ *
+ * If the socket is in a non-blocking mode this call will not return TRUE until
+ * p_socket_check_connect_result() is called. The socket will be closed if
+ * p_socket_shutdown() is called for both the directions.
+ */
+P_LIB_API pboolean p_socket_is_closed (const PSocket *socket);
+
+/**
+ * @brief Checks a connection state after calling p_socket_connect().
+ * @param socket #PSocket to check the connection state for.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE if was no error, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_io_condition_wait()
+ * @warning Not supported on Syllable for connection-less sockets.
+ *
+ * Usually this call is used after calling p_socket_connect() on a socket in a
+ * non-blocking mode to check the connection state. If call returns the FALSE
+ * result then the connection checking call has failed or there was an error
+ * during the connection and you should check the last error using an @a error
+ * object.
+ *
+ * If the socket is still pending for the connection you will get the
+ * #P_ERROR_IO_IN_PROGRESS error code.
+ *
+ * After calling p_socket_connect() on a non-blocking socket, you can wait for
+ * a connection operation to be finished using p_socket_io_condition_wait()
+ * with the #P_SOCKET_IO_CONDITION_POLLOUT option.
+ */
+P_LIB_API pboolean p_socket_check_connect_result (PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Sets the @a socket SO_KEEPALIVE flag.
+ * @param socket #PSocket to set the SO_KEEPALIVE flag for.
+ * @param keepalive Value for the SO_KEEPALIVE flag.
+ * @since 0.0.1
+ * @sa p_socket_get_keepalive()
+ *
+ * See p_socket_get_keepalive() documentation for a description of this option.
+ */
+P_LIB_API void p_socket_set_keepalive (PSocket *socket,
+ pboolean keepalive);
+
+/**
+ * @brief Sets a @a socket blocking mode.
+ * @param socket #PSocket to set the blocking mode for.
+ * @param blocking Whether to set the @a socket into the blocking mode.
+ * @note A blocking socket will wait for an I/O operation to be completed
+ * before returning to the caller function.
+ * @note On some operating systems a blocking timeout may be less than threads
+ * scheduling granularity, so the actual timeout can be greater than specified
+ * one.
+ * @since 0.0.1
+ * @sa p_socket_get_blocking()
+ */
+P_LIB_API void p_socket_set_blocking (PSocket *socket,
+ pboolean blocking);
+
+/**
+ * @brief Sets a @a socket listen backlog parameter.
+ * @param socket #PSocket to set the listen backlog parameter for.
+ * @param backlog Value for the listen backlog parameter.
+ * @note This parameter can take effect only if it was set before calling
+ * p_socket_listen(). Otherwise it will be ignored by underlying socket
+ * system calls.
+ * @since 0.0.1
+ * @sa p_socket_get_listen_backlog()
+ *
+ * See p_socket_get_listen_backlog() documentation for a description of this
+ * option.
+ */
+P_LIB_API void p_socket_set_listen_backlog (PSocket *socket,
+ pint backlog);
+
+/**
+ * @brief Sets a @a socket timeout value for blocking I/O operations.
+ * @param socket #PSocket to set the @a timeout for.
+ * @param timeout Timeout value in milliseconds.
+ * @since 0.0.1
+ * @sa p_socket_get_timeoout(), p_socket_io_condition_wait()
+ *
+ * See p_socket_get_timeout() documentation for a description of this option.
+ */
+P_LIB_API void p_socket_set_timeout (PSocket *socket,
+ pint timeout);
+
+/**
+ * @brief Binds a @a socket to a given local address.
+ * @param socket #PSocket to bind.
+ * @param address #PSocketAddress to bind the given @a socket to.
+ * @param allow_reuse Whether to allow socket's address reusing.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_get_local_address()
+ *
+ * The @a allow_reuse option allows to resolve address conflicts for several
+ * bound sockets. It controls the SO_REUSEADDR socket flag.
+ *
+ * In a common case two or more sockets can't be bound to the same address
+ * (a network address and a port) for the same data transfer protocol (i.e. TCP
+ * or UDP) because they will be in a conflicted state for data receiving. But
+ * the socket can be also bound for the any network interface (i.e. 0.0.0.0
+ * network address) and a particular port. If you will try to bind another
+ * socket without the @a allow_reuse option to a particular network address
+ * (i.e. 127.0.0.1) and the same port, the p_socket_bind() call will fail.
+ *
+ * With the @a allow_reuse option the system will resolve this conflict: the
+ * socket will be bound to the particular address and port (and will receive
+ * data targeted to this particular address) while the first socket will be
+ * receiving all other data matching the bound address.
+ *
+ * This option is system dependent, some systems do not support it. Also some
+ * systems have option to reuse the address port (SO_REUSEPORT) in the same way,
+ * too.
+ *
+ * Connection oriented sockets have another problem - the so called linger time.
+ * It is a time required by the system to properly close a socket connection
+ * (and this process can be quite complicated). This time can be measured from
+ * several minutes to several hours (!). The socket in such a state is
+ * half-dead, but it holds the bound address and attempt to bind another socket
+ * on this address will fail. The @a allow_reuse option allows to bind another
+ * socket on such a half-dead address, but behavior can be unexpected, it's
+ * better to refer to the system documentation for that.
+ *
+ * In general case, a server socket should be bound with the @a allow_reuse set
+ * to TRUE, while a client socket shouldn't set this option to TRUE. If you
+ * restart the client quickly with the same address it can fail to bind.
+ */
+P_LIB_API pboolean p_socket_bind (const PSocket *socket,
+ PSocketAddress *address,
+ pboolean allow_reuse,
+ PError **error);
+
+/**
+ * @brief Connects a @a socket to a given remote address.
+ * @param socket #PSocket to connect.
+ * @param address #PSocketAddress to connect the @a socket to.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_is_connected(), p_socket_check_connect_result(),
+ * p_socket_get_remote_address(), p_socket_io_condition_wait()
+ * @warning On Syllable this method changes a local port of the connection
+ * oriented socket in case of success.
+ *
+ * Calling this method on the connection-less socket will bind it to the remote
+ * address and the p_socket_send() method can be used instead of
+ * p_socket_send_to(), so you do not need to specify the remote (target) address
+ * each time you need to send data. The socket will also discard incoming data
+ * from other addresses. The same call again will re-bind it to another remote
+ * address.
+ *
+ * For the connection oriented socket it tries to establish a connection with
+ * a listening remote socket. The same call again will have no effect and will
+ * fail.
+ *
+ * If the @a socket is in a non-blocking mode, then you can wait for the
+ * connection using p_socket_io_condition_wait() with the
+ * #P_SOCKET_IO_CONDITION_POLLOUT parameter. You should check the connection
+ * result after that using p_socket_check_connect_result().
+ */
+P_LIB_API pboolean p_socket_connect (PSocket *socket,
+ PSocketAddress *address,
+ PError **error);
+
+/**
+ * @brief Puts a @a socket into a listening state.
+ * @param socket #PSocket to start listening.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_get_listen_backlog(), p_socket_set_listen_backlog()
+ *
+ * This call has meaning only for connection oriented sockets. Before starting
+ * to accept incoming connections, the socket must be put into the passive mode
+ * using p_socket_listen(). After that p_socket_accept() can be used to
+ * accept incoming connections.
+ *
+ * Maximum number of pending connections is defined by the backlog parameter,
+ * see p_socket_get_listen_backlog() documentation for more information. The
+ * backlog parameter must be set before calling p_socket_listen() to take
+ * effect.
+ */
+P_LIB_API pboolean p_socket_listen (PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Accepts a @a socket incoming connection.
+ * @param socket #PSocket to accept the incoming connection from.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return New #PSocket with the accepted connection in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ *
+ * This call has meaning only for connection oriented sockets. The socket can
+ * accept new incoming connections only after calling p_socket_bind() and
+ * p_socket_listen().
+ */
+P_LIB_API PSocket * p_socket_accept (const PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Receives data from a given @a socket.
+ * @param socket #PSocket to receive data from.
+ * @param buffer Buffer to write received data in.
+ * @param buflen Length of @a buffer.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Size in bytes of written data in case of success, -1 otherwise.
+ * @note If the @a socket is in a blocking mode, then the caller will be blocked
+ * until data arrives.
+ * @since 0.0.1
+ * @sa p_socket_receive_from(), p_socket_connect()
+ *
+ * If the @a buflen is less than the received data size, only @a buflen bytes of
+ * data will be written to the @a buffer, and excess bytes may be discarded
+ * depending on a socket message type.
+ *
+ * This call is normally used only with the a connected socket, see
+ * p_socket_connect().
+ */
+P_LIB_API pssize p_socket_receive (const PSocket *socket,
+ pchar *buffer,
+ psize buflen,
+ PError **error);
+
+/**
+ * @brief Receives data from a given @a socket and saves a remote address.
+ * @param socket #PSocket to receive data from.
+ * @param[out] address Pointer to store the remote address in case of success,
+ * may be NULL. The caller is responsible to free it after usage.
+ * @param buffer Buffer to write received data in.
+ * @param buflen Length of @a buffer.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Size in bytes of written data in case of success, -1 otherwise.
+ * @note If the @a socket is in a blocking mode, then the caller will be blocked
+ * until data arrives.
+ * @since 0.0.1
+ * @sa p_socket_receive()
+ *
+ * If the @a buflen is less than the received data size, only @a buflen bytes of
+ * data will be written to the @a buffer, and excess bytes may be discarded
+ * depending on a socket message type.
+ *
+ * This call is normally used only with a connection-less socket.
+ */
+P_LIB_API pssize p_socket_receive_from (const PSocket *socket,
+ PSocketAddress **address,
+ pchar *buffer,
+ psize buflen,
+ PError **error);
+
+/**
+ * @brief Sends data through a given @a socket.
+ * @param socket #PSocket to send data through.
+ * @param buffer Buffer with data to send.
+ * @param buflen Length of @a buffer.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Size in bytes of sent data in case of success, -1 otherwise.
+ * @note If the @a socket is in a blocking mode, then the caller will be blocked
+ * until data sent.
+ * @since 0.0.1
+ * @sa p_socket_send_to()
+ *
+ * Do not use this call for connection-less sockets which are not connected to a
+ * remote address using p_socket_connect() because it will always fail, use
+ * p_socket_send_to() instead.
+ */
+P_LIB_API pssize p_socket_send (const PSocket *socket,
+ const pchar *buffer,
+ psize buflen,
+ PError **error);
+
+/**
+ * @brief Sends data through a given @a socket to a given address.
+ * @param socket #PSocket to send data through.
+ * @param address #PSocketAddress to send data to.
+ * @param buffer Buffer with data to send.
+ * @param buflen Length of @a buffer.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return Size in bytes of sent data in case of success, -1 otherwise.
+ * @note If the @a socket is in a blocking mode, then the caller will be blocked
+ * until data sent.
+ * @since 0.0.1
+ * @sa p_socket_send()
+ *
+ * This call is used when dealing with connection-less sockets. You can bind
+ * such a socket to a remote address using p_socket_connect() and use
+ * p_socket_send() instead. If you are working with connection oriented sockets
+ * then use p_socket_send() after establishing a connection.
+ */
+P_LIB_API pssize p_socket_send_to (const PSocket *socket,
+ PSocketAddress *address,
+ const pchar *buffer,
+ psize buflen,
+ PError **error);
+
+/**
+ * @brief Closes a @a socket.
+ * @param socket #PSocket to close.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_free(), p_socket_is_closed()
+ *
+ * For connection oriented sockets some time is required to completely close
+ * a socket connection. See documentation for p_socket_bind() for more
+ * information.
+ */
+P_LIB_API pboolean p_socket_close (PSocket *socket,
+ PError **error);
+
+/**
+ * @brief Shutdowns a full-duplex @a socket data transfer link.
+ * @param socket #PSocket to shutdown link.
+ * @param shutdown_read Whether to shutdown the incoming data transfer link.
+ * @param shutdown_write Whether to shutdown the outcoming data transfer link.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @note Shutdown of any link is possible only on the socket in a connected
+ * state, otherwise the call will fail.
+ * @since 0.0.1
+ *
+ * After shutdowning the data transfer link couldn't be restored in any
+ * direction. It is often used to gracefully close a connection for a connection
+ * oriented socket.
+ */
+P_LIB_API pboolean p_socket_shutdown (PSocket *socket,
+ pboolean shutdown_read,
+ pboolean shutdown_write,
+ PError **error);
+
+/**
+ * @brief Closes a @a socket (if not closed yet) and frees its resources.
+ * @param socket #PSocket to free resources from.
+ * @since 0.0.1
+ * @sa p_socket_close()
+ */
+P_LIB_API void p_socket_free (PSocket *socket);
+
+/**
+ * @brief Sets the @a socket buffer size for a given data transfer direction.
+ * @param socket #PSocket to set the buffer size for.
+ * @param dir Direction to set the buffer size on.
+ * @param size Size of the buffer to set, in bytes.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ * @warning Not supported on Syllable.
+ */
+P_LIB_API pboolean p_socket_set_buffer_size (const PSocket *socket,
+ PSocketDirection dir,
+ psize size,
+ PError **error);
+
+/**
+ * @brief Waits for a specified I/O @a condition on @a socket.
+ * @param socket #PSocket to wait for @a condition on.
+ * @param condition An I/O condition to wait for on @a socket.
+ * @param[out] error Error report object, NULL to ignore.
+ * @return TRUE if @a condition has been met, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_get_timeout(), p_socket_set_timeout()
+ *
+ * Waits until @a condition will be met on @a socket or an error occurred. If
+ * timeout was set using p_socket_set_timeout() and a network I/O operation
+ * doesn't finish until timeout expired, call will fail with
+ * #P_ERROR_IO_TIMED_OUT error code.
+ */
+P_LIB_API pboolean p_socket_io_condition_wait (const PSocket *socket,
+ PSocketIOCondition condition,
+ PError **error);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSOCKET_H */
diff --git a/3rdparty/plibsys/src/psocketaddress.c b/3rdparty/plibsys/src/psocketaddress.c
new file mode 100644
index 0000000..2338c83
--- /dev/null
+++ b/3rdparty/plibsys/src/psocketaddress.c
@@ -0,0 +1,619 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pstring.h"
+#include "psocketaddress.h"
+#include "plibsys-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef P_OS_WIN
+# include <arpa/inet.h>
+#endif
+
+#if defined (PLIBSYS_HAS_GETADDRINFO) && !defined (PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID)
+# undef PLIBSYS_HAS_GETADDRINFO
+#endif
+
+#ifdef PLIBSYS_HAS_GETADDRINFO
+# include <netdb.h>
+#endif
+
+/* According to Open Group specifications */
+#ifndef INET_ADDRSTRLEN
+# ifdef P_OS_WIN
+ /* On Windows it includes port number */
+# define INET_ADDRSTRLEN 22
+# else
+# define INET_ADDRSTRLEN 16
+# endif
+#endif
+
+#ifdef AF_INET6
+# ifndef INET6_ADDRSTRLEN
+# ifdef P_OS_WIN
+ /* On Windows it includes port number */
+# define INET6_ADDRSTRLEN 65
+# else
+# define INET6_ADDRSTRLEN 46
+# endif
+# endif
+#endif
+
+#ifdef P_OS_VMS
+# if PLIBSYS_SIZEOF_VOID_P == 8
+# define addrinfo __addrinfo64
+# endif
+#endif
+
+#if defined (P_OS_BEOS) || defined (P_OS_OS2)
+# ifdef AF_INET6
+# undef AF_INET6
+# endif
+#endif
+
+struct PSocketAddress_ {
+ PSocketFamily family;
+ union addr_ {
+ struct in_addr sin_addr;
+#ifdef AF_INET6
+ struct in6_addr sin6_addr;
+#endif
+ } addr;
+ puint16 port;
+ puint32 flowinfo;
+ puint32 scope_id;
+};
+
+P_LIB_API PSocketAddress *
+p_socket_address_new_from_native (pconstpointer native,
+ psize len)
+{
+ PSocketAddress *ret;
+ puint16 family;
+
+ if (P_UNLIKELY (native == NULL || len == 0))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL))
+ return NULL;
+
+ family = ((struct sockaddr *) native)->sa_family;
+
+ if (family == AF_INET) {
+ if (len < sizeof (struct sockaddr_in)) {
+ P_WARNING ("PSocketAddress::p_socket_address_new_from_native: invalid IPv4 native size");
+ p_free (ret);
+ return NULL;
+ }
+
+ memcpy (&ret->addr.sin_addr, &((struct sockaddr_in *) native)->sin_addr, sizeof (struct in_addr));
+ ret->family = P_SOCKET_FAMILY_INET;
+ ret->port = p_ntohs (((struct sockaddr_in *) native)->sin_port);
+ return ret;
+ }
+#ifdef AF_INET6
+ else if (family == AF_INET6) {
+ if (len < sizeof (struct sockaddr_in6)) {
+ P_WARNING ("PSocketAddress::p_socket_address_new_from_native: invalid IPv6 native size");
+ p_free (ret);
+ return NULL;
+ }
+
+ memcpy (&ret->addr.sin6_addr,
+ &((struct sockaddr_in6 *) native)->sin6_addr,
+ sizeof (struct in6_addr));
+
+ ret->family = P_SOCKET_FAMILY_INET6;
+ ret->port = p_ntohs (((struct sockaddr_in *) native)->sin_port);
+#ifdef PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO
+ ret->flowinfo = ((struct sockaddr_in6 *) native)->sin6_flowinfo;
+#endif
+#ifdef PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID
+ ret->scope_id = ((struct sockaddr_in6 *) native)->sin6_scope_id;
+#endif
+ return ret;
+ }
+#endif
+ else {
+ p_free (ret);
+ return NULL;
+ }
+}
+
+P_LIB_API PSocketAddress *
+p_socket_address_new (const pchar *address,
+ puint16 port)
+{
+ PSocketAddress *ret;
+#if defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)
+ struct addrinfo hints;
+ struct addrinfo *res;
+#endif
+
+#ifdef P_OS_WIN
+ struct sockaddr_storage sa;
+ struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
+# ifdef AF_INET6
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sa;
+# endif /* AF_INET6 */
+ pint len;
+#endif /* P_OS_WIN */
+
+ if (P_UNLIKELY (address == NULL))
+ return NULL;
+
+#if (defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)) && defined (AF_INET6)
+ if (strchr (address, ':') != NULL) {
+ memset (&hints, 0, sizeof (hints));
+
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+# ifndef P_OS_UNIXWARE
+ hints.ai_flags = AI_NUMERICHOST;
+# endif
+
+ if (P_UNLIKELY (getaddrinfo (address, NULL, &hints, &res) != 0))
+ return NULL;
+
+ if (P_LIKELY (res->ai_family == AF_INET6 &&
+ res->ai_addrlen == sizeof (struct sockaddr_in6))) {
+ ((struct sockaddr_in6 *) res->ai_addr)->sin6_port = p_htons (port);
+ ret = p_socket_address_new_from_native (res->ai_addr, res->ai_addrlen);
+ } else
+ ret = NULL;
+
+ freeaddrinfo (res);
+
+ return ret;
+ }
+#endif
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL)) {
+ P_ERROR ("PSocketAddress::p_socket_address_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->port = port;
+
+#ifdef P_OS_WIN
+ memset (&sa, 0, sizeof (sa));
+ len = sizeof (sa);
+ sin->sin_family = AF_INET;
+
+ if (WSAStringToAddressA ((LPSTR) address, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0) {
+ memcpy (&ret->addr.sin_addr, &sin->sin_addr, sizeof (struct in_addr));
+ ret->family = P_SOCKET_FAMILY_INET;
+ return ret;
+ }
+# ifdef AF_INET6
+ else {
+ sin6->sin6_family = AF_INET6;
+
+ if (WSAStringToAddressA ((LPSTR) address, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0) {
+ memcpy (&ret->addr.sin6_addr, &sin6->sin6_addr, sizeof (struct in6_addr));
+ ret->family = P_SOCKET_FAMILY_INET6;
+ return ret;
+ }
+ }
+# endif /* AF_INET6 */
+#else /* P_OS_WIN */
+ if (inet_pton (AF_INET, address, &ret->addr.sin_addr) > 0) {
+ ret->family = P_SOCKET_FAMILY_INET;
+ return ret;
+ }
+# ifdef AF_INET6
+ else if (inet_pton (AF_INET6, address, &ret->addr.sin6_addr) > 0) {
+ ret->family = P_SOCKET_FAMILY_INET6;
+ return ret;
+ }
+# endif /* AF_INET6 */
+#endif /* P_OS_WIN */
+
+ p_free (ret);
+ return NULL;
+}
+
+P_LIB_API PSocketAddress *
+p_socket_address_new_any (PSocketFamily family,
+ puint16 port)
+{
+ PSocketAddress *ret;
+ puchar any_addr[] = {0, 0, 0, 0};
+#ifdef AF_INET6
+ struct in6_addr any6_addr = IN6ADDR_ANY_INIT;
+#endif
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL)) {
+ P_ERROR ("PSocketAddress::p_socket_address_new_any: failed to allocate memory");
+ return NULL;
+ }
+
+ if (family == P_SOCKET_FAMILY_INET)
+ memcpy (&ret->addr.sin_addr, any_addr, sizeof (any_addr));
+#ifdef AF_INET6
+ else if (family == P_SOCKET_FAMILY_INET6)
+ memcpy (&ret->addr.sin6_addr, &any6_addr.s6_addr, sizeof (any6_addr.s6_addr));
+#endif
+ else {
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->family = family;
+ ret->port = port;
+
+ return ret;
+}
+
+P_LIB_API PSocketAddress *
+p_socket_address_new_loopback (PSocketFamily family,
+ puint16 port)
+{
+ PSocketAddress *ret;
+ puchar loop_addr[] = {127, 0, 0, 0};
+#ifdef AF_INET6
+ struct in6_addr loop6_addr = IN6ADDR_LOOPBACK_INIT;
+#endif
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL)) {
+ P_ERROR ("PSocketAddress::p_socket_address_new_loopback: failed to allocate memory");
+ return NULL;
+ }
+
+ if (family == P_SOCKET_FAMILY_INET)
+ memcpy (&ret->addr.sin_addr, loop_addr, sizeof (loop_addr));
+#ifdef AF_INET6
+ else if (family == P_SOCKET_FAMILY_INET6)
+ memcpy (&ret->addr.sin6_addr, &loop6_addr.s6_addr, sizeof (loop6_addr.s6_addr));
+#endif
+ else {
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->family = family;
+ ret->port = port;
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_socket_address_to_native (const PSocketAddress *addr,
+ ppointer dest,
+ psize destlen)
+{
+ struct sockaddr_in *sin;
+#ifdef AF_INET6
+ struct sockaddr_in6 *sin6;
+#endif
+
+ if (P_UNLIKELY (addr == NULL || dest == NULL || destlen == 0))
+ return FALSE;
+
+ sin = (struct sockaddr_in *) dest;
+#ifdef AF_INET6
+ sin6 = (struct sockaddr_in6 *) dest;
+#endif
+
+ if (addr->family == P_SOCKET_FAMILY_INET) {
+ if (P_UNLIKELY (destlen < sizeof (struct sockaddr_in))) {
+ P_WARNING ("PSocketAddress::p_socket_address_to_native: invalid buffer size for IPv4");
+ return FALSE;
+ }
+
+ memcpy (&sin->sin_addr, &addr->addr.sin_addr, sizeof (struct in_addr));
+ sin->sin_family = AF_INET;
+ sin->sin_port = p_htons (addr->port);
+ memset (sin->sin_zero, 0, sizeof (sin->sin_zero));
+ return TRUE;
+ }
+#ifdef AF_INET6
+ else if (addr->family == P_SOCKET_FAMILY_INET6) {
+ if (P_UNLIKELY (destlen < sizeof (struct sockaddr_in6))) {
+ P_ERROR ("PSocketAddress::p_socket_address_to_native: invalid buffer size for IPv6");
+ return FALSE;
+ }
+
+ memcpy (&sin6->sin6_addr, &addr->addr.sin6_addr, sizeof (struct in6_addr));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = p_htons (addr->port);
+#ifdef PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO
+ sin6->sin6_flowinfo = addr->flowinfo;
+#endif
+#ifdef PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID
+ sin6->sin6_scope_id = addr->scope_id;
+#endif
+ return TRUE;
+ }
+#endif
+ else {
+ P_WARNING ("PSocketAddress::p_socket_address_to_native: unsupported socket address");
+ return FALSE;
+ }
+}
+
+P_LIB_API psize
+p_socket_address_get_native_size (const PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return 0;
+
+ if (addr->family == P_SOCKET_FAMILY_INET)
+ return sizeof (struct sockaddr_in);
+#ifdef AF_INET6
+ else if (addr->family == P_SOCKET_FAMILY_INET6)
+ return sizeof (struct sockaddr_in6);
+#endif
+ else {
+ P_WARNING ("PSocketAddress::p_socket_address_get_native_size: unsupported socket family");
+ return 0;
+ }
+}
+
+P_LIB_API PSocketFamily
+p_socket_address_get_family (const PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return P_SOCKET_FAMILY_UNKNOWN;
+
+ return addr->family;
+}
+
+P_LIB_API pchar *
+p_socket_address_get_address (const PSocketAddress *addr)
+{
+#ifdef AF_INET6
+ pchar buffer[INET6_ADDRSTRLEN];
+#else
+ pchar buffer[INET_ADDRSTRLEN];
+#endif
+
+#ifdef P_OS_WIN
+ DWORD buflen = sizeof (buffer);
+ DWORD addrlen;
+ struct sockaddr_storage sa;
+ struct sockaddr_in *sin;
+# ifdef AF_INET6
+ struct sockaddr_in6 *sin6;
+# endif /* AF_INET6 */
+#endif /* P_OS_WIN */
+
+ if (P_UNLIKELY (addr == NULL || addr->family == P_SOCKET_FAMILY_UNKNOWN))
+ return NULL;
+#ifdef P_OS_WIN
+ sin = (struct sockaddr_in *) &sa;
+# ifdef AF_INET6
+ sin6 = (struct sockaddr_in6 *) &sa;
+# endif /* AF_INET6 */
+#endif /* P_OS_WIN */
+
+#ifdef P_OS_WIN
+ memset (&sa, 0, sizeof (sa));
+#endif
+
+#ifdef P_OS_WIN
+ sa.ss_family = addr->family;
+
+ if (addr->family == P_SOCKET_FAMILY_INET) {
+ addrlen = sizeof (struct sockaddr_in);
+ memcpy (&sin->sin_addr, &addr->addr.sin_addr, sizeof (struct in_addr));
+ }
+# ifdef AF_INET6
+ else {
+ addrlen = sizeof (struct sockaddr_in6);
+ memcpy (&sin6->sin6_addr, &addr->addr.sin6_addr, sizeof (struct in6_addr));
+ }
+# endif /* AF_INET6 */
+
+ if (P_UNLIKELY (WSAAddressToStringA ((LPSOCKADDR) &sa,
+ addrlen,
+ NULL,
+ (LPSTR) buffer,
+ &buflen) != 0))
+ return NULL;
+#else /* !P_OS_WIN */
+ if (addr->family == P_SOCKET_FAMILY_INET)
+ inet_ntop (AF_INET, &addr->addr.sin_addr, buffer, sizeof (buffer));
+# ifdef AF_INET6
+ else
+ inet_ntop (AF_INET6, &addr->addr.sin6_addr, buffer, sizeof (buffer));
+# endif /* AF_INET6 */
+#endif /* P_OS_WIN */
+
+ return p_strdup (buffer);
+}
+
+P_LIB_API puint16
+p_socket_address_get_port (const PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return 0;
+
+ return addr->port;
+}
+
+P_LIB_API puint32
+p_socket_address_get_flow_info (const PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return 0;
+
+#if !defined (AF_INET6) || !defined (PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO)
+ return 0;
+#else
+ if (P_UNLIKELY (addr->family != P_SOCKET_FAMILY_INET6))
+ return 0;
+
+ return addr->flowinfo;
+#endif
+}
+
+P_LIB_API puint32
+p_socket_address_get_scope_id (const PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return 0;
+
+#if !defined (AF_INET6) || !defined (PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID)
+ return 0;
+#else
+ if (P_UNLIKELY (addr->family != P_SOCKET_FAMILY_INET6))
+ return 0;
+
+ return addr->scope_id;
+#endif
+}
+
+P_LIB_API void
+p_socket_address_set_flow_info (PSocketAddress *addr,
+ puint32 flowinfo)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return;
+
+#if !defined (AF_INET6) || !defined (PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO)
+ P_UNUSED (flowinfo);
+ return;
+#else
+ if (P_UNLIKELY (addr->family != P_SOCKET_FAMILY_INET6))
+ return;
+
+ addr->flowinfo = flowinfo;
+#endif
+}
+
+P_LIB_API void
+p_socket_address_set_scope_id (PSocketAddress *addr,
+ puint32 scope_id)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return;
+
+#if !defined (AF_INET6) || !defined (PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID)
+ P_UNUSED (scope_id);
+ return;
+#else
+ if (P_UNLIKELY (addr->family != P_SOCKET_FAMILY_INET6))
+ return;
+
+ addr->scope_id = scope_id;
+#endif
+}
+
+P_LIB_API pboolean
+p_socket_address_is_flow_info_supported (void)
+{
+#ifdef AF_INET6
+# ifdef PLIBSYS_SOCKADDR_IN6_HAS_FLOWINFO
+ return TRUE;
+# else
+ return FALSE;
+# endif
+#else
+ return FALSE;
+#endif
+}
+
+P_LIB_API pboolean
+p_socket_address_is_scope_id_supported (void)
+{
+#ifdef AF_INET6
+# ifdef PLIBSYS_SOCKADDR_IN6_HAS_SCOPEID
+ return TRUE;
+# else
+ return FALSE;
+# endif
+#else
+ return FALSE;
+#endif
+}
+
+P_LIB_API pboolean
+p_socket_address_is_ipv6_supported (void)
+{
+#ifdef AF_INET6
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+P_LIB_API pboolean
+p_socket_address_is_any (const PSocketAddress *addr)
+{
+ puint32 addr4;
+
+ if (P_UNLIKELY (addr == NULL || addr->family == P_SOCKET_FAMILY_UNKNOWN))
+ return FALSE;
+
+ if (addr->family == P_SOCKET_FAMILY_INET) {
+ addr4 = p_ntohl (* ((puint32 *) &addr->addr.sin_addr));
+
+ return (addr4 == INADDR_ANY);
+ }
+#ifdef AF_INET6
+ else
+ return IN6_IS_ADDR_UNSPECIFIED (&addr->addr.sin6_addr);
+#else
+ else
+ return FALSE;
+#endif
+}
+
+P_LIB_API pboolean
+p_socket_address_is_loopback (const PSocketAddress *addr)
+{
+ puint32 addr4;
+
+ if (P_UNLIKELY (addr == NULL || addr->family == P_SOCKET_FAMILY_UNKNOWN))
+ return FALSE;
+
+ if (addr->family == P_SOCKET_FAMILY_INET) {
+ addr4 = p_ntohl (* ((puint32 *) &addr->addr.sin_addr));
+
+ /* 127.0.0.0/8 */
+ return ((addr4 & 0xff000000) == 0x7f000000);
+ }
+#ifdef AF_INET6
+ else
+ return IN6_IS_ADDR_LOOPBACK (&addr->addr.sin6_addr);
+#else
+ else
+ return FALSE;
+#endif
+}
+
+P_LIB_API void
+p_socket_address_free (PSocketAddress *addr)
+{
+ if (P_UNLIKELY (addr == NULL))
+ return;
+
+ p_free (addr);
+}
diff --git a/3rdparty/plibsys/src/psocketaddress.h b/3rdparty/plibsys/src/psocketaddress.h
new file mode 100644
index 0000000..d77ca1c
--- /dev/null
+++ b/3rdparty/plibsys/src/psocketaddress.h
@@ -0,0 +1,284 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file psocketaddress.h
+ * @brief Socket address wrapper
+ * @author Alexander Saprykin
+ *
+ * A socket address is usually represented by a network address (IPv4 or IPv6)
+ * and a port number (though some other naming schemes and parameters are
+ * possible).
+ *
+ * Socket address parameters are stored inside a special system (native)
+ * structure in the binary (raw) form. The native structure varies with an
+ * operating system and a network protocol. #PSocketAddress acts like a thin
+ * wrapper around that native address structure and unifies manipulation of
+ * socket address data.
+ *
+ * #PSocketAddress supports IPv4 and IPv6 addresses which consist of an IP
+ * address and a port number. IPv6 support is system dependent and not provided
+ * for all the platforms. Sometimes you may also need to enable IPv6 support in
+ * the system to make it working.
+ *
+ * Convenient methods to create special addresses are provided: for the loopback
+ * interface use p_socket_address_new_loopback(), for the any-address interface
+ * use p_socket_address_new_any().
+ *
+ * If you want to get the underlying native address structure for further usage
+ * in system calls use p_socket_address_to_native(), and
+ * p_socket_address_new_from_native() for a vice versa conversion.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSOCKETADDRESS_H
+#define PLIBSYS_HEADER_PSOCKETADDRESS_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+#ifndef P_OS_WIN
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+#endif
+
+P_BEGIN_DECLS
+
+/** Socket address family. */
+typedef enum PSocketFamily_ {
+ P_SOCKET_FAMILY_UNKNOWN = 0, /**< Unknown family. */
+ P_SOCKET_FAMILY_INET = AF_INET, /**< IPv4 family. */
+#ifdef AF_INET6
+ P_SOCKET_FAMILY_INET6 = AF_INET6 /**< IPv6 family. */
+#else
+ P_SOCKET_FAMILY_INET6 = -1 /**< No IPv6 family. */
+#endif
+} PSocketFamily;
+
+/** Socket address opaque structure. */
+typedef struct PSocketAddress_ PSocketAddress;
+
+/**
+ * @brief Creates new #PSocketAddress from the native socket address raw data.
+ * @param native Pointer to the native socket address raw data.
+ * @param len Raw data length, in bytes.
+ * @return Pointer to #PSocketAddress in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PSocketAddress * p_socket_address_new_from_native (pconstpointer native,
+ psize len);
+
+/**
+ * @brief Creates new #PSocketAddress.
+ * @param address String representation of an address (i.e. "172.146.45.5").
+ * @param port Port number.
+ * @return Pointer to #PSocketAddress in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note It tries to automatically detect a socket family.
+ *
+ * If the @a address is an IPv6 address, it can also contain a scope index
+ * separated from the address by the '%' literal). Most target platforms should
+ * correctly parse such an address though some old operating systems may fail in
+ * case of lack of the getaddrinfo() call.
+ */
+P_LIB_API PSocketAddress * p_socket_address_new (const pchar *address,
+ puint16 port);
+
+/**
+ * @brief Creates new #PSocketAddress for the any-address representation.
+ * @param family Socket family.
+ * @param port Port number.
+ * @return Pointer to #PSocketAddress in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note This call creates a network address for the set of all possible
+ * addresses, so you can't use it for receiving or sending data on a particular
+ * network address. If you need to bind a socket to the specific address
+ * (i.e. 127.0.0.1) use p_socket_address_new() instead.
+ */
+P_LIB_API PSocketAddress * p_socket_address_new_any (PSocketFamily family,
+ puint16 port);
+
+/**
+ * @brief Creates new #PSocketAddress for the loopback interface.
+ * @param family Socket family.
+ * @param port Port number.
+ * @return Pointer to #PSocketAddress in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note This call creates a network address for the entire loopback network
+ * interface, so you can't use it for receiving or sending data on a particular
+ * network address. If you need to bind a socket to the specific address
+ * (i.e. 127.0.0.1) use p_socket_address_new() instead.
+ */
+P_LIB_API PSocketAddress * p_socket_address_new_loopback (PSocketFamily family,
+ puint16 port);
+
+/**
+ * @brief Converts #PSocketAddress to the native socket address raw data.
+ * @param addr #PSocketAddress to convert.
+ * @param[out] dest Output buffer for raw data.
+ * @param destlen Length in bytes of the @a dest buffer.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_socket_address_to_native (const PSocketAddress *addr,
+ ppointer dest,
+ psize destlen);
+
+/**
+ * @brief Gets the size of the native socket address raw data, in bytes.
+ * @param addr #PSocketAddress to get the size of native address raw data for.
+ * @return Size of the native socket address raw data in case of success, 0
+ * otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API psize p_socket_address_get_native_size (const PSocketAddress *addr);
+
+/**
+ * @brief Gets a family of a socket address.
+ * @param addr #PSocketAddress to get the family for.
+ * @return #PSocketFamily of the socket address.
+ * @since 0.0.1
+ */
+P_LIB_API PSocketFamily p_socket_address_get_family (const PSocketAddress *addr);
+
+/**
+ * @brief Gets a socket address in a string representation, i.e. "172.146.45.5".
+ * @param addr #PSocketAddress to get address string for.
+ * @return Pointer to the string representation of the socket address in case of
+ * success, NULL otherwise. The caller takes ownership of the returned pointer.
+ * @since 0.0.1
+ */
+P_LIB_API pchar * p_socket_address_get_address (const PSocketAddress *addr);
+
+/**
+ * @brief Gets a port number of a socket address.
+ * @param addr #PSocketAddress to get the port number for.
+ * @return Port number in case of success, 0 otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API puint16 p_socket_address_get_port (const PSocketAddress *addr);
+
+/**
+ * @brief Gets IPv6 traffic class and flow information.
+ * @param addr #PSocketAddress to get flow information for.
+ * @return IPv6 traffic class and flow information.
+ * @since 0.0.1
+ * @note This call is valid only for an IPv6 address, otherwise 0 is returned.
+ * @note Some operating systems may not support this property.
+ * @sa p_socket_address_is_flow_info_supported()
+ */
+P_LIB_API puint32 p_socket_address_get_flow_info (const PSocketAddress *addr);
+
+/**
+ * @brief Gets an IPv6 set of interfaces for a scope.
+ * @param addr #PSocketAddress to get the set of interfaces for.
+ * @return Index that identifies the set of interfaces for a scope.
+ * @since 0.0.1
+ * @note This call is valid only for an IPv6 address, otherwise 0 is returned.
+ * @note Some operating systems may not support this property.
+ * @sa p_socket_address_is_scope_id_supported()
+ */
+P_LIB_API puint32 p_socket_address_get_scope_id (const PSocketAddress *addr);
+
+/**
+ * @brief Sets IPv6 traffic class and flow information.
+ * @param addr #PSocketAddress to set flow information for.
+ * @param flowinfo Flow information to set.
+ * @since 0.0.1
+ * @note This call is valid only for an IPv6 address.
+ * @note Some operating systems may not support this property.
+ * @sa p_socket_address_is_flow_info_supported()
+ */
+P_LIB_API void p_socket_address_set_flow_info (PSocketAddress *addr,
+ puint32 flowinfo);
+
+/**
+ * @brief Sets an IPv6 set of interfaces for a scope.
+ * @param addr #PSocketAddress to set the set of interfaces for.
+ * @param scope_id Index that identifies the set of interfaces for a scope.
+ * @since 0.0.1
+ * @note This call is valid only for an IPv6 address.
+ * @note Some operating systems may not support this property.
+ * @sa p_socket_address_is_scope_id_supported()
+ */
+P_LIB_API void p_socket_address_set_scope_id (PSocketAddress *addr,
+ puint32 scope_id);
+
+/**
+ * @brief Checks whether flow information is supported in IPv6.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_socket_address_is_flow_info_supported (void);
+
+/**
+ * @brief Checks whether a set of interfaces for a scope is supported in IPv6.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_socket_address_is_scope_id_supported (void);
+
+/**
+ * @brief Checks whether IPv6 protocol is supported.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.3
+ */
+P_LIB_API pboolean p_socket_address_is_ipv6_supported (void);
+
+/**
+ * @brief Checks whether a given socket address is an any-address
+ * representation. Such an address is a 0.0.0.0.
+ * @param addr #PSocketAddress to check.
+ * @return TRUE if the @a addr is the any-address representation, FALSE
+ * otherwise.
+ * @since 0.0.1
+ * @sa p_socket_address_new_any()
+ */
+P_LIB_API pboolean p_socket_address_is_any (const PSocketAddress *addr);
+
+/**
+ * @brief Checks whether a given socket address is for the loopback interface.
+ * Such an address is a 127.x.x.x.
+ * @param addr #PSocketAddress to check.
+ * @return TRUE if the @a addr is for the loopback interface, FALSE otherwise.
+ * @since 0.0.1
+ * @sa p_socket_address_new_loopback()
+ */
+P_LIB_API pboolean p_socket_address_is_loopback (const PSocketAddress *addr);
+
+/**
+ * @brief Frees a socket address structure and its resources.
+ * @param addr #PSocketAddress to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_socket_address_free (PSocketAddress *addr);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSOCKETADDRESS_H */
diff --git a/3rdparty/plibsys/src/pspinlock-c11.c b/3rdparty/plibsys/src/pspinlock-c11.c
new file mode 100644
index 0000000..1e77954
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock-c11.c
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pspinlock.h"
+
+#ifdef P_CC_SUN
+# define PSPINLOCK_INT_CAST(x) (pint *) (x)
+#else
+# define PSPINLOCK_INT_CAST(x) x
+#endif
+
+struct PSpinLock_ {
+ volatile pint spin;
+};
+
+P_LIB_API PSpinLock *
+p_spinlock_new (void)
+{
+ PSpinLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_spinlock_lock (PSpinLock *spinlock)
+{
+ pint tmp_int;
+
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ do {
+ tmp_int = 0;
+ } while ((pboolean) __atomic_compare_exchange_n (PSPINLOCK_INT_CAST (&(spinlock->spin)),
+ &tmp_int,
+ 1,
+ 0,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED) == FALSE);
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_spinlock_trylock (PSpinLock *spinlock)
+{
+ pint tmp_int = 0;
+
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return (pboolean) __atomic_compare_exchange_n (PSPINLOCK_INT_CAST (&(spinlock->spin)),
+ &tmp_int,
+ 1,
+ 0,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
+}
+
+P_LIB_API pboolean
+p_spinlock_unlock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ __atomic_store_4 (PSPINLOCK_INT_CAST (&(spinlock->spin)), 0, __ATOMIC_RELEASE);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_spinlock_free (PSpinLock *spinlock)
+{
+ p_free (spinlock);
+}
diff --git a/3rdparty/plibsys/src/pspinlock-decc.c b/3rdparty/plibsys/src/pspinlock-decc.c
new file mode 100644
index 0000000..0a5a044
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock-decc.c
@@ -0,0 +1,87 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pspinlock.h"
+
+#ifdef P_OS_VMS
+# include <builtins.h>
+#else
+# include <machine/builtins.h>
+#endif
+
+struct PSpinLock_ {
+ volatile pint spin;
+};
+
+P_LIB_API PSpinLock *
+p_spinlock_new (void)
+{
+ PSpinLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_spinlock_lock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ (void) __LOCK_LONG ((volatile void *) &(spinlock->spin));
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_spinlock_trylock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return __LOCK_LONG_RETRY ((volatile void *) &(spinlock->spin), 1) == 1 ? TRUE : FALSE;
+}
+
+P_LIB_API pboolean
+p_spinlock_unlock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ (void) __UNLOCK_LONG ((volatile void *) &(spinlock->spin));
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_spinlock_free (PSpinLock *spinlock)
+{
+ p_free (spinlock);
+}
diff --git a/3rdparty/plibsys/src/pspinlock-sim.c b/3rdparty/plibsys/src/pspinlock-sim.c
new file mode 100644
index 0000000..bf9479f
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock-sim.c
@@ -0,0 +1,88 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+#include "pspinlock.h"
+
+struct PSpinLock_ {
+ PMutex *mutex;
+};
+
+P_LIB_API PSpinLock *
+p_spinlock_new (void)
+{
+ PSpinLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->mutex = p_mutex_new ()) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: p_mutex_new() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_spinlock_lock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return p_mutex_lock (spinlock->mutex);
+}
+
+P_LIB_API pboolean
+p_spinlock_trylock (PSpinLock *spinlock)
+{
+ if (spinlock == NULL)
+ return FALSE;
+
+ return p_mutex_trylock (spinlock->mutex);
+}
+
+P_LIB_API pboolean
+p_spinlock_unlock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return p_mutex_unlock (spinlock->mutex);
+}
+
+P_LIB_API void
+p_spinlock_free (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return;
+
+ p_mutex_free (spinlock->mutex);
+ p_free (spinlock);
+}
diff --git a/3rdparty/plibsys/src/pspinlock-sync.c b/3rdparty/plibsys/src/pspinlock-sync.c
new file mode 100644
index 0000000..e15e2a8
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock-sync.c
@@ -0,0 +1,83 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pspinlock.h"
+
+struct PSpinLock_ {
+ volatile pint spin;
+};
+
+P_LIB_API PSpinLock *
+p_spinlock_new (void)
+{
+ PSpinLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_spinlock_lock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ while ((pboolean) __sync_bool_compare_and_swap (&(spinlock->spin), 0, 1) == FALSE)
+ ;
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_spinlock_trylock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return (pboolean) __sync_bool_compare_and_swap (&(spinlock->spin), 0, 1);
+}
+
+P_LIB_API pboolean
+p_spinlock_unlock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ spinlock->spin = 0;
+ __sync_synchronize ();
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_spinlock_free (PSpinLock *spinlock)
+{
+ p_free (spinlock);
+}
diff --git a/3rdparty/plibsys/src/pspinlock-win.c b/3rdparty/plibsys/src/pspinlock-win.c
new file mode 100644
index 0000000..73ccbdc
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock-win.c
@@ -0,0 +1,83 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "pspinlock.h"
+
+struct PSpinLock_ {
+ volatile pint spin;
+};
+
+P_LIB_API PSpinLock *
+p_spinlock_new (void)
+{
+ PSpinLock *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) {
+ P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory");
+ return NULL;
+ }
+
+ return ret;
+}
+
+P_LIB_API pboolean
+p_spinlock_lock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ while (p_atomic_int_compare_and_exchange (&(spinlock->spin), 0, 1) == FALSE)
+ ;
+
+ return TRUE;
+}
+
+P_LIB_API pboolean
+p_spinlock_trylock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ return p_atomic_int_compare_and_exchange (&(spinlock->spin), 0, 1);
+}
+
+P_LIB_API pboolean
+p_spinlock_unlock (PSpinLock *spinlock)
+{
+ if (P_UNLIKELY (spinlock == NULL))
+ return FALSE;
+
+ p_atomic_int_set (&(spinlock->spin), 0);
+
+ return TRUE;
+}
+
+P_LIB_API void
+p_spinlock_free (PSpinLock *spinlock)
+{
+ p_free (spinlock);
+}
diff --git a/3rdparty/plibsys/src/pspinlock.h b/3rdparty/plibsys/src/pspinlock.h
new file mode 100644
index 0000000..aac3b3b
--- /dev/null
+++ b/3rdparty/plibsys/src/pspinlock.h
@@ -0,0 +1,142 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pspinlock.h
+ * @brief Light-weight atomic spinlock
+ * @author Alexander Saprykin
+ *
+ * A spinlock is an inter-thread synchronization primitive based on atomic
+ * operations. It allows to guard a critical section from concurrent access of
+ * multiple threads at once. It is very similar to a mutex in semantics, but
+ * inside it provides a more light-weight and fast locking mechanism without
+ * thread sleeping and undesirable context switching. Thus spinlocks should be
+ * used only for small code sections, otherwise long-time spinning can cause
+ * extensive CPU time waste by waiting threads.
+ *
+ * As the spinlock is based on atomic operations it would have the real meaning
+ * only if an underlying atomic model is lock-free (not simulated using the
+ * mutex). You can check if the atomic model is lock-free with
+ * p_atomic_is_lock_free(). Otherwise usage of spinlocks will be the same as the
+ * ordinary mutex.
+ *
+ * To create a new spinlock primitive the p_spinlock_new() routine should be
+ * called, to delete the unused spinlock primitive use p_spinlock_free().
+ *
+ * Use p_spinlock_lock() or p_spinlock_trylock() to synchronize access at the
+ * beginning of the critical section. Only the one thread is allowed to pass
+ * this call, others will wait for the p_spinlock_unlock() call which marks the
+ * end of the critical section. This way the critical section code is guarded
+ * against concurrent access of multiple threads at once.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSPINLOCK_H
+#define PLIBSYS_HEADER_PSPINLOCK_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Spinlock opaque data structure. */
+typedef struct PSpinLock_ PSpinLock;
+
+/**
+ * @brief Creates a new #PSpinLock object.
+ * @return Pointer to a newly created #PSpinLock object.
+ * @since 0.0.1
+ */
+P_LIB_API PSpinLock * p_spinlock_new (void);
+
+/**
+ * @brief Locks a spinlock.
+ * @param spinlock #PSpinLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * A thread will not sleep in this call if another thread is holding the lock,
+ * instead it will try to lock @a spinlock in an infinite loop.
+ *
+ * If the atomic model is not lock-free this call will have the same effect
+ * as p_mutex_lock().
+ *
+ * Do not lock a spinlock recursively - this may lead to an application
+ * deadlock.
+ */
+P_LIB_API pboolean p_spinlock_lock (PSpinLock *spinlock);
+
+/**
+ * @brief Tries to lock a spinlock immediately.
+ * @param spinlock #PSpinLock to lock.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * Tries to lock @a spinlock and returns immediately if it is not available for
+ * locking.
+ *
+ * If the atomic model is not lock-free this call will have the same effect
+ * as p_mutex_trylock().
+ *
+ * Do not lock a spinlock recursively - this may lead to an application
+ * deadlock.
+ */
+P_LIB_API pboolean p_spinlock_trylock (PSpinLock *spinlock);
+
+/**
+ * @brief Releases a locked spinlock.
+ * @param spinlock #PSpinLock to release.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ *
+ * If @a spinlock was previously locked then it becomes unlocked. Any thread
+ * can unlock any spinlock. It is also safe to call this routine on an unlocked
+ * spinlock.
+ *
+ * If the atomic model is not lock-free this call will have the same effect
+ * as p_mutex_unlock(), thus it is not safe to call this routine on an unlocked
+ * spinlock.
+ */
+P_LIB_API pboolean p_spinlock_unlock (PSpinLock *spinlock);
+
+/**
+ * @brief Frees #PSpinLock object.
+ * @param spinlock #PSpinLock to free.
+ * @since 0.0.1
+ *
+ * It doesn't unlock @a spinlock before freeing memory, so you should do it
+ * manually.
+ *
+ * If the atomic model is not lock-free this call will have the same effect
+ * as p_mutex_free().
+ */
+P_LIB_API void p_spinlock_free (PSpinLock *spinlock);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSPINLOCK_H */
diff --git a/3rdparty/plibsys/src/pstdarg.h b/3rdparty/plibsys/src/pstdarg.h
new file mode 100644
index 0000000..bd12f8a
--- /dev/null
+++ b/3rdparty/plibsys/src/pstdarg.h
@@ -0,0 +1,318 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Jean-Damien Durand <jeandamiendurand@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pstdarg.h
+ * @brief Variable arguments
+ * @author Jean-Damien Durand
+ *
+ * Functions declared with a variable number of arguments use macros to step
+ * through them.
+ *
+ * The #p_va_list type must be declared in such function, #p_va_start,
+ * #p_va_arg and #p_va_end are used to initialize, to step through and to end
+ * the navigation, respectively.
+ *
+ * A variable number of arguments can be propagated to another function which
+ * accepts a #p_va_list parameter, using #p_va_copy.
+ *
+ * Any use of #p_va_start or #p_va_copy must have a corresponding #p_va_end.
+ *
+ * Using a variable number of parameters requires a known-in-advance contract
+ * between the caller and the callee on the number of parameters and their types.
+ * Note, that this mechanism is a weakly typed: the compiler will always apply
+ * default type promotion, regardless if you explicitely typecast an argument in
+ * the stack, i.e.:
+ * - Integer arguments of types lower than #pint are always promoted to #pint,
+ * or #puint if #pint is not enough.
+ * - Arguments of type @a float are always promoted to @a double.
+ * - Arrays are always promoted to pointers.
+ *
+ * You need to be very careful when using variable arguments. Improper usage may
+ * lead to program crash. In order to avoid type casting mistakes, consider
+ * using macros for variable arguments with explicit type casting provided below.
+ * Though you still can use #p_va_arg if you know what are you doing.
+ *
+ * Please note, that stdarg.h implementation is not compatible with varargs.h,
+ * and only one of them should be used in a compilation unit. You must be sure
+ * that you don't use varargs.h along with the current implmenetation, otherwise
+ * runtime failures are inevitable.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSTDARG_H
+#define PLIBSYS_HEADER_PSTDARG_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#ifndef PLIBSYS_VA_COPY
+# include <string.h>
+#endif
+
+/**
+ * @brief Opaque type holding variable number of arguments navigation.
+ * @since 0.0.4
+ */
+#define p_va_list va_list
+
+/**
+ * @brief Initializes navigation through a variable number of arguments.
+ * @param ap Declared object of type #p_va_list.
+ * @param last Name of the last argument before @a ap.
+ * @since 0.0.4
+ * @note There must be a corresponding call to #p_va_end(ap) afterwards.
+ */
+#define p_va_start(ap, last) va_start(ap, last)
+
+/**
+ * @brief Gets the next argument in the list.
+ * @param ap Declared object of type va_list, previously initalized with
+ * #p_va_start.
+ * @param type Type of the next argument.
+ * @return Value of the next argument.
+ * @since 0.0.4
+ */
+
+#define p_va_arg(ap, type) (type) va_arg(ap, type)
+
+/**
+ * @brief Ends the navigation.
+ * @param ap Declared object of type #p_va_list.
+ * @since 0.0.4
+ * @note There must be a corresponding call to #p_va_start(ap) before.
+ */
+#define p_va_end(ap) va_end(ap)
+
+/**
+ * @brief Copies a navigation object.
+ * @param dst Destination object of type #p_va_list.
+ * @param src Source object of type #p_va_list.
+ * @since 0.0.4
+ * @note The state of @a src is copied as well, @a dst is initialized as if
+ * #p_va_start(dst) would have been called. There must be a corresponding call
+ * to #p_va_end(dst) afterwards.
+ */
+#ifdef PLIBSYS_VA_COPY
+# define p_va_copy(dst, src) PLIBSYS_VA_COPY(dst, src)
+#else
+# define p_va_copy(dst, src) ((void) memcpy (&(dst), &(src), sizeof (va_list)))
+#endif
+
+/**
+ * @def pint8_va_arg
+ * @brief Unstacks a #pint8 variable.
+ * @param ap #p_va_list stack.
+ * @return #pint8 value.
+ * @since 0.0.4
+ */
+#define pint8_va_arg(ap) ((pint8) p_va_arg(ap, pint))
+
+/**
+ * @def puint8_va_arg
+ * @brief Unstacks a #puint8 variable.
+ * @param ap #p_va_list stack.
+ * @return #puint8 value.
+ * @since 0.0.4
+ */
+#define puint8_va_arg(ap) ((puint8) p_va_arg(ap, puint))
+
+/**
+ * @def pint16_va_arg
+ * @brief Unstacks a #pint16 variable.
+ * @param ap #p_va_list stack.
+ * @return #pint16 value.
+ * @since 0.0.4
+ */
+#define pint16_va_arg(ap) ((pint16) p_va_arg(ap, pint))
+
+/**
+ * @def puint16_va_arg
+ * @brief Unstacks a #puint16 variable.
+ * @param ap #p_va_list stack.
+ * @return #puint16 value.
+ * @since 0.0.4
+ */
+#define puint16_va_arg(ap) ((puint16) p_va_arg(ap, puint))
+
+/**
+ * @def pint32_va_arg
+ * @brief Unstacks a #pint32 variable.
+ * @param ap #p_va_list stack.
+ * @return #pint32 value.
+ * @since 0.0.4
+ */
+#define pint32_va_arg(ap) ((pint32) p_va_arg(ap, pint))
+
+/**
+ * @def puint32_va_arg
+ * @brief Unstacks a #puint32 variable.
+ * @param ap #p_va_list stack.
+ * @return #puint32 value.
+ * @since 0.0.4
+ */
+#define puint32_va_arg(ap) ((puint32) p_va_arg(ap, puint))
+
+/**
+ * @def pint64_va_arg
+ * @brief Unstacks a #pint64 variable.
+ * @param ap #p_va_list stack.
+ * @return #pint64 value.
+ * @since 0.0.4
+ */
+#define pint64_va_arg(ap) (p_va_arg(ap, pint64))
+
+/**
+ * @def puint64_va_arg
+ * @brief Unstacks a #puint64 variable.
+ * @param ap #p_va_list stack.
+ * @return #puint64 value.
+ * @since 0.0.4
+ */
+#define puint64_va_arg(ap) (p_va_arg(ap, puint64))
+
+/**
+ * @def ppointer_va_arg
+ * @brief Unstacks a #ppointer variable.
+ * @param ap #p_va_list stack.
+ * @return #ppointer value.
+ * @since 0.0.4
+ */
+#define ppointer_va_arg(ap) (p_va_arg(ap, ppointer))
+
+/**
+ * @def pconstpointer_va_arg
+ * @brief Unstacks a #pconstpointer variable.
+ * @param ap #p_va_list stack.
+ * @return #pconstpointer value.
+ * @since 0.0.4
+ */
+#define pconstpointer_va_arg(ap) (p_va_arg(ap, pconstpointer))
+
+/**
+ * @def pboolean_va_arg
+ * @brief Unstacks a #pboolean variable.
+ * @param ap #p_va_list stack.
+ * @return #pboolean value.
+ * @since 0.0.4
+ */
+#define pboolean_va_arg(ap) ((pboolean) p_va_arg(ap, pint))
+
+/**
+ * @def pchar_va_arg
+ * @brief Unstacks a #pchar variable.
+ * @param ap #p_va_list stack.
+ * @return #pchar value.
+ * @since 0.0.4
+ */
+#define pchar_va_arg(ap) ((pchar) p_va_arg(ap, pint))
+
+/**
+ * @def pshort_va_arg
+ * @brief Unstacks a #pshort variable.
+ * @param ap #p_va_list stack.
+ * @return #pshort value.
+ * @since 0.0.4
+ */
+#define pshort_va_arg(ap) ((pshort) p_va_arg(ap, pint))
+
+/**
+ * @def pint_va_arg
+ * @brief Unstacks a #pint variable.
+ * @param ap #p_va_list stack.
+ * @return #pint value.
+ * @since 0.0.4
+ */
+#define pint_va_arg(ap) (p_va_arg(ap, pint))
+
+/**
+ * @def plong_va_arg
+ * @brief Unstacks a #plong variable.
+ * @param ap #p_va_list stack.
+ * @return #plong value.
+ * @since 0.0.4
+ */
+#define plong_va_arg(ap) (p_va_arg(ap, plong))
+
+/**
+ * @def puchar_va_arg
+ * @brief Unstacks a #puchar variable.
+ * @param ap #p_va_list stack.
+ * @return #puchar value.
+ * @since 0.0.4
+ */
+#define puchar_va_arg(ap) ((puchar) p_va_arg(ap, puint))
+
+/**
+ * @def pushort_va_arg
+ * @brief Unstacks a #pushort variable.
+ * @param ap #p_va_list stack.
+ * @return #pushort value.
+ * @since 0.0.4
+ */
+#define pushort_va_arg(ap) ((pushort) p_va_arg(ap, puint))
+
+/**
+ * @def puint_va_arg
+ * @brief Unstacks a #puint variable.
+ * @param ap #p_va_list stack.
+ * @return #puint value.
+ * @since 0.0.4
+ */
+#define puint_va_arg(ap) (p_va_arg(ap, puint))
+
+/**
+ * @def pulong_va_arg
+ * @brief Unstacks a #pulong variable.
+ * @param ap #p_va_list stack.
+ * @return #pulong value.
+ * @since 0.0.4
+ */
+#define pulong_va_arg(ap) (p_va_arg(ap, pulong))
+
+/**
+ * @def pfloat_va_arg
+ * @brief Unstacks a #pfloat variable.
+ * @param ap #p_va_list stack.
+ * @return #pfloat value.
+ * @since 0.0.4
+ */
+#define pfloat_va_arg(ap) ((pfloat) p_va_arg(ap, pdouble))
+
+/**
+ * @def pdouble_va_arg
+ * @brief Unstacks a #pdouble variable.
+ * @param ap #p_va_list stack.
+ * @return #pdouble value.
+ * @since 0.0.4
+ */
+#define pdouble_va_arg(ap) (p_va_arg(ap, pdouble))
+
+#endif /* PLIBSYS_HEADER_PSTDARG_H */
diff --git a/3rdparty/plibsys/src/pstring.c b/3rdparty/plibsys/src/pstring.c
new file mode 100644
index 0000000..ed46ec5
--- /dev/null
+++ b/3rdparty/plibsys/src/pstring.c
@@ -0,0 +1,206 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2011-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ * Copyright (C) 2009 Tom Van Baak (tvb) www.LeapSecond.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pstring.h"
+
+#include <string.h>
+#include <ctype.h>
+
+#define P_STR_MAX_EXPON 308
+
+P_LIB_API pchar *
+p_strdup (const pchar *str)
+{
+ pchar *ret;
+ psize len;
+
+ if (P_UNLIKELY (str == NULL))
+ return NULL;
+
+ len = strlen (str) + 1;
+
+ if (P_UNLIKELY ((ret = p_malloc (len)) == NULL))
+ return NULL;
+
+ memcpy (ret, str, len);
+
+ return ret;
+}
+
+P_LIB_API pchar *
+p_strchomp (const pchar *str)
+{
+ pssize pos_start, pos_end;
+ psize str_len;
+ pchar *ret;
+ const pchar *ptr;
+
+ if (P_UNLIKELY (str == NULL))
+ return NULL;
+
+ ptr = str;
+ pos_start = 0;
+ pos_end = ((pssize) strlen (str)) - 1;
+
+ while (pos_start < pos_end && isspace (* ((const puchar *) ptr++)))
+ ++pos_start;
+
+ ptr = str + pos_end;
+
+ while (pos_end > 0 && isspace (* ((const puchar *) ptr--)))
+ --pos_end;
+
+ if (pos_end < pos_start)
+ return p_strdup ("\0");
+
+ if (pos_end == pos_start && isspace (* ((const puchar *) (str + pos_end))))
+ return p_strdup ("\0");
+
+ str_len = (psize) (pos_end - pos_start + 2);
+
+ if (P_UNLIKELY ((ret = p_malloc0 (str_len)) == NULL))
+ return NULL;
+
+ memcpy (ret, str + pos_start, str_len - 1);
+ *(ret + str_len - 1) = '\0';
+
+ return ret;
+}
+
+P_LIB_API pchar *
+p_strtok (pchar *str, const pchar *delim, pchar **buf)
+{
+ if (P_UNLIKELY (delim == NULL))
+ return str;
+
+#ifdef P_OS_WIN
+# ifdef P_CC_MSVC
+ if (P_UNLIKELY (buf == NULL))
+ return str;
+# if _MSC_VER < 1400
+ P_UNUSED (buf);
+ return strtok (str, delim);
+# else
+ return strtok_s (str, delim, buf);
+# endif
+# else
+ P_UNUSED (buf);
+ return strtok (str, delim);
+# endif
+#else
+ if (P_UNLIKELY (buf == NULL))
+ return str;
+
+ return strtok_r (str, delim, buf);
+#endif
+}
+
+P_LIB_API double
+p_strtod (const pchar *str)
+{
+ double sign;
+ double value;
+ double scale;
+ double pow10;
+ puint expon;
+ pint frac;
+ pchar *orig_str, *strp;
+
+ orig_str = p_strchomp (str);
+
+ if (P_UNLIKELY (orig_str == NULL))
+ return 0.0;
+
+ strp = orig_str;
+ sign = 1.0;
+
+ if (*strp == '-') {
+ sign = -1.0;
+ strp += 1;
+ } else if (*strp == '+')
+ strp += 1;
+
+ /* Get digits before decimal point or exponent, if any */
+ for (value = 0.0; isdigit ((pint) *strp); strp += 1)
+ value = value * 10.0 + (*strp - '0');
+
+ /* Get digits after decimal point, if any */
+ if (*strp == '.') {
+ pow10 = 10.0;
+ strp += 1;
+
+ while (isdigit ((pint) *strp)) {
+ value += (*strp - '0') / pow10;
+ pow10 *= 10.0;
+ strp += 1;
+ }
+ }
+
+ /* Handle exponent, if any */
+ frac = 0;
+ scale = 1.0;
+
+ if ((*strp == 'e') || (*strp == 'E')) {
+ /* Get sign of exponent, if any */
+ strp += 1;
+
+ if (*strp == '-') {
+ frac = 1;
+ strp += 1;
+
+ } else if (*strp == '+')
+ strp += 1;
+
+ /* Get digits of exponent, if any */
+ for (expon = 0; isdigit ((pint) *strp); strp += 1)
+ expon = expon * 10 + (puint) ((*strp - '0'));
+
+ if (P_UNLIKELY (expon > P_STR_MAX_EXPON))
+ expon = P_STR_MAX_EXPON;
+
+ /* Calculate scaling factor */
+ while (expon >= 50) {
+ scale *= 1e50;
+ expon -= 50;
+ }
+
+ while (expon >= 8) {
+ scale *= 1e8;
+ expon -= 8;
+ }
+
+ while (expon > 0) {
+ scale *= 10.0;
+ expon -= 1;
+ }
+ }
+
+ p_free (orig_str);
+
+ /* Return signed and scaled floating point result */
+ return sign * (frac ? (value / scale) : (value * scale));
+}
diff --git a/3rdparty/plibsys/src/pstring.h b/3rdparty/plibsys/src/pstring.h
new file mode 100644
index 0000000..76ebf9d
--- /dev/null
+++ b/3rdparty/plibsys/src/pstring.h
@@ -0,0 +1,117 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2011-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file pstring.h
+ * @brief String manipulation routines
+ * @author Alexander Saprykin
+ *
+ * Strings are represented as a sequence of single-byte characters (from the
+ * ASCII table) with the trailing zero character (\0).
+ *
+ * Some useful string manipulation routines are represented here.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSTRING_H
+#define PLIBSYS_HEADER_PSTRING_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Copies a string.
+ * @param str String with the trailing zero to copy.
+ * @return Copy of the @a str in case of success, NULL otherwise. The caller
+ * takes ownership of the returned string.
+ * @since 0.0.1
+ */
+P_LIB_API pchar * p_strdup (const pchar *str);
+
+/**
+ * @brief Removes trailing and leading whitespaces.
+ * @param str String with the trailing zero to process.
+ * @return Newlly allocated string in case of success, NULL otherwise. The
+ * caller takes ownership of the returned string.
+ * @since 0.0.1
+ */
+P_LIB_API pchar * p_strchomp (const pchar *str);
+
+/**
+ * @brief Tokenizes a string by given delimiters.
+ * @param[in,out] str String to tokenize.
+ * @param delim List of delimiters to split the string.
+ * @param buf Context to store tokenize info.
+ * @return Pointer to a splitted zero-terminated string in case of success, NULL
+ * otherwise.
+ * @since 0.0.1
+ * @note The @a str is modified by this call, so take care for that. The
+ * returned pointer points on a @a str substring, so you do not need to call
+ * p_free() on it.
+ *
+ * The common usage of this call is following:
+ * @code
+ * pchar *token, *buf;
+ * pchar str[] = "This is a test string"
+ * pchar delim[] = " \t"
+ * ...
+ * token = p_strtok (str, delim, &buf);
+ *
+ * while (token != NULL) {
+ * printf ("Splitted string: %s\n", token);
+ * token = p_strtok (NULL, delim, &buf);
+ * }
+ * @endcode
+ * Take attention that you need to pass the original string only once, after
+ * that you should pass NULL instead. You can also pass different delimiters
+ * each time.
+ *
+ * Some platforms do not support the third parameter and it can be remained
+ * unused. In that case this call wouldn't be thread-safe.
+ */
+P_LIB_API pchar * p_strtok (pchar *str,
+ const pchar *delim,
+ pchar **buf);
+
+/**
+ * @brief Converts a string to @a double without a locale dependency.
+ * @param str String to convert.
+ * @return Floating point value in case of success, 0 otherwise.
+ * @since 0.0.1
+ *
+ * Since the atof() system call is locale dependent, you can use this call to
+ * convert string variables to @a double values. The decimal point is '.' as in
+ * the 'C' locale.
+ */
+P_LIB_API double p_strtod (const pchar *str);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSTRING_H */
diff --git a/3rdparty/plibsys/src/psysclose-darwin.c b/3rdparty/plibsys/src/psysclose-darwin.c
new file mode 100644
index 0000000..7c44024
--- /dev/null
+++ b/3rdparty/plibsys/src/psysclose-darwin.c
@@ -0,0 +1,93 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Copyright 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * http://crbug.com/269623
+ * http://openradar.appspot.com/14999594
+ *
+ * When the default version of close used on macOS fails with EINTR, the
+ * file descriptor is not in a deterministic state. It may have been closed,
+ * or it may not have been. This makes it impossible to gracefully recover
+ * from the error. If the close is retried after the FD has been closed, the
+ * subsequent close can report EBADF, or worse, it can close an unrelated FD
+ * opened by another thread. If the close is not retried after the FD has been
+ * left open, the FD is leaked. Neither of these are good options.
+ *
+ * macOS provides an alternate version of close, close$NOCANCEL. This
+ * version will never fail with EINTR before the FD is actually closed. With
+ * this version, it is thus safe to call close without checking for EINTR (as
+ * the HANDLE_EINTR macro does) and not risk leaking the FD. In fact, mixing
+ * this verison of close with HANDLE_EINTR is hazardous.
+ *
+ * The $NOCANCEL variants of various system calls are activated by compiling
+ * with __DARWIN_NON_CANCELABLE, which prevents them from being pthread
+ * cancellation points. Rather than taking such a heavy-handed approach, this
+ * file implements an alternative: to use the $NOCANCEL variant of close (thus
+ * preventing it from being a pthread cancellation point) without affecting
+ * any other system calls.
+ *
+ * This file operates by providing a close function with the non-$NOCANCEL
+ * symbol name expected for the compilation environment as set by <unistd.h>
+ * and <sys/cdefs.h> (the DARWIN_ALIAS_C macro). That function calls the
+ * $NOCANCEL variant, which is resolved from libsyscall. By linking with this
+ * version of close prior to the libsyscall version, close's implementation is
+ * overridden.
+ */
+
+#include <sys/cdefs.h>
+
+/* If the non-cancelable variants of all system calls have already been chosen,
+ * do nothing. */
+#if !__DARWIN_NON_CANCELABLE
+# if __DARWIN_UNIX03 && !__DARWIN_ONLY_UNIX_CONFORMANCE
+/* When there's a choice between UNIX2003 and pre-UNIX2003 and UNIX2003 has
+ * been chosen. */
+extern int close$NOCANCEL$UNIX2003 (int fd);
+# define PLIBSYS_CLOSE_INTERFACE close$NOCANCEL$UNIX2003
+# elif !__DARWIN_UNIX03 && !__DARWIN_ONLY_UNIX_CONFORMANCE
+/* When there's a choice between UNIX2003 and pre-UNIX2003 and pre-UNIX2003
+ * has been chosen. There's no close$NOCANCEL symbol in this case, so use
+ * close$NOCANCEL$UNIX2003 as the implementation. It does the same thing that
+ * close$NOCANCEL would do. */
+extern int close$NOCANCEL$UNIX2003 (int fd);
+# define PLIBSYS_CLOSE_INTERFACE close$NOCANCEL$UNIX2003
+# else
+/* When only UNIX2003 is supported. */
+extern int close$NOCANCEL (int fd);
+# define PLIBSYS_CLOSE_INTERFACE close$NOCANCEL
+# endif
+#endif
+
+#include "psysclose-private.h"
+
+pint
+p_sys_close (pint fd)
+{
+ return PLIBSYS_CLOSE_INTERFACE (fd);
+}
diff --git a/3rdparty/plibsys/src/psysclose-private.h b/3rdparty/plibsys/src/psysclose-private.h
new file mode 100644
index 0000000..629e2cb
--- /dev/null
+++ b/3rdparty/plibsys/src/psysclose-private.h
@@ -0,0 +1,47 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PSYSCLOSE_PRIVATE_H
+#define PLIBSYS_HEADER_PSYSCLOSE_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+
+P_BEGIN_DECLS
+
+/**
+ * @brief Safely closes a file descriptor.
+ * @param fd File descriptor to close.
+ * @return -1 in case of success, 0 otherwise.
+ */
+pint p_sys_close (pint fd);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PSYSCLOSE_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/psysclose-unix.c b/3rdparty/plibsys/src/psysclose-unix.c
new file mode 100644
index 0000000..1a43dd6
--- /dev/null
+++ b/3rdparty/plibsys/src/psysclose-unix.c
@@ -0,0 +1,54 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "perror.h"
+#include "psysclose-private.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+pint
+p_sys_close (pint fd)
+{
+#if defined (EINTR) && defined (P_OS_HPUX)
+ pint res, err_code;
+
+ for (;;) {
+ res = close (fd);
+
+ if (P_LIKELY (res == 0))
+ return 0;
+
+ err_code = p_error_get_last_system ();
+
+ if (err_code == EINTR)
+ continue;
+ else
+ return -1;
+ }
+#else
+ return close (fd);
+#endif
+}
diff --git a/3rdparty/plibsys/src/psysclose-win.c b/3rdparty/plibsys/src/psysclose-win.c
new file mode 100644
index 0000000..57f83b5
--- /dev/null
+++ b/3rdparty/plibsys/src/psysclose-win.c
@@ -0,0 +1,33 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "psysclose-private.h"
+
+pint
+p_sys_close (pint fd)
+{
+ /* On Windows we can only close a socket descriptor */
+ return closesocket (fd) == 0 ? 0 : -1;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-amiga.c b/3rdparty/plibsys/src/ptimeprofiler-amiga.c
new file mode 100644
index 0000000..c90f1d7
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-amiga.c
@@ -0,0 +1,70 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <proto/timer.h>
+
+static puint64 pp_time_profiler_freq = 1;
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ struct EClockVal eclock;
+
+ ITimer->ReadEClock (&eclock);
+
+ return (((puint64) eclock.ev_hi) * pp_time_profiler_freq + (puint64) eclock.ev_lo);
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ puint64 value;
+
+ value = p_time_profiler_get_ticks_internal ();
+
+ /* Check for register overflow */
+
+ if (P_UNLIKELY (value < profiler->counter))
+ value += (((puint64) 1) << 32) * pp_time_profiler_freq;
+
+ return (value - profiler->counter) * 1000000ULL / pp_time_profiler_freq;
+}
+
+void
+p_time_profiler_init (void)
+{
+ struct EClockVal eclock;
+
+ pp_time_profiler_freq = (puint64) ITimer->ReadEClock (&eclock);
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+ pp_time_profiler_freq = 1;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-beos.c b/3rdparty/plibsys/src/ptimeprofiler-beos.c
new file mode 100644
index 0000000..8d651d7
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-beos.c
@@ -0,0 +1,51 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <kernel/OS.h>
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ return (puint64) system_time ();
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return ((puint64) system_time ()) - profiler->counter;
+}
+
+void
+p_time_profiler_init (void)
+{
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-generic.c b/3rdparty/plibsys/src/ptimeprofiler-generic.c
new file mode 100644
index 0000000..d984d47
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-generic.c
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <time.h>
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ pint64 val;
+
+ if (P_UNLIKELY ((val = (pint64) time (NULL)) == -1)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_get_ticks_internal: time() failed");
+ return 0;
+ }
+
+ return (puint64) (val * 1000000);
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return p_time_profiler_get_ticks_internal () - profiler->counter;
+}
+
+void
+p_time_profiler_init (void)
+{
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-mach.c b/3rdparty/plibsys/src/ptimeprofiler-mach.c
new file mode 100644
index 0000000..6bef3c7
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-mach.c
@@ -0,0 +1,73 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <mach/mach_time.h>
+
+static puint64 pp_time_profiler_freq_num = 0;
+static puint64 pp_time_profiler_freq_denom = 0;
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ puint64 val = mach_absolute_time ();
+
+ /* To prevent overflow */
+ val /= 1000;
+
+ val *= pp_time_profiler_freq_num;
+ val /= pp_time_profiler_freq_denom;
+
+ return val;
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return p_time_profiler_get_ticks_internal () - profiler->counter;
+}
+
+void
+p_time_profiler_init (void)
+{
+ mach_timebase_info_data_t tb;
+
+ if (P_UNLIKELY (mach_timebase_info (&tb) != KERN_SUCCESS || tb.denom == 0)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_init: mach_timebase_info() failed");
+ return;
+ }
+
+ pp_time_profiler_freq_num = (puint64) tb.numer;
+ pp_time_profiler_freq_denom = (puint64) tb.denom;
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+ pp_time_profiler_freq_num = 0;
+ pp_time_profiler_freq_denom = 0;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-os2.c b/3rdparty/plibsys/src/ptimeprofiler-os2.c
new file mode 100644
index 0000000..e511bd1
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-os2.c
@@ -0,0 +1,107 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#define INCL_DOSPROFILE
+#define INCL_DOSERRORS
+#include <os2.h>
+
+#if PLIBSYS_HAS_LLDIV
+# ifdef P_CC_GNU
+# define __USE_ISOC99
+# endif
+# include <stdlib.h>
+#endif
+
+static puint64 pp_time_profiler_freq = 1;
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ union {
+ puint64 ticks;
+ QWORD tcounter;
+ } tick_time;
+
+ if (P_UNLIKELY (DosTmrQueryTime (&tick_time.tcounter) != NO_ERROR)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_get_ticks_internal: DosTmrQueryTime() failed");
+ return 0;
+ }
+
+ return tick_time.ticks;
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ puint64 ticks;
+#if PLIBSYS_HAS_LLDIV
+ lldiv_t ldres;
+#endif
+ puint64 quot;
+ puint64 rem;
+
+ ticks = p_time_profiler_get_ticks_internal ();
+
+ if (ticks < profiler->counter) {
+ P_WARNING ("PTimeProfiler::p_time_profiler_elapsed_usecs_internal: negative jitter");
+ return 1;
+ }
+
+ ticks -= profiler->counter;
+
+#if PLIBSYS_HAS_LLDIV
+ ldres = lldiv ((long long) ticks, (long long) pp_time_profiler_freq);
+
+ quot = ldres.quot;
+ rem = ldres.rem;
+#else
+ quot = ticks / pp_time_profiler_freq;
+ rem = ticks % pp_time_profiler_freq;
+#endif
+
+ return (puint64) (quot * 1000000LL + (rem * 1000000LL) / pp_time_profiler_freq);
+}
+
+void
+p_time_profiler_init (void)
+{
+ ULONG freq;
+
+ if (P_UNLIKELY (DosTmrQueryFreq (&freq) != NO_ERROR)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_init: DosTmrQueryFreq() failed");
+ return;
+ }
+
+ pp_time_profiler_freq = (puint64) freq;
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+ pp_time_profiler_freq = 1;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-posix.c b/3rdparty/plibsys/src/ptimeprofiler-posix.c
new file mode 100644
index 0000000..b913bbb
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-posix.c
@@ -0,0 +1,109 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+
+#ifndef _POSIX_MONOTONIC_CLOCK
+# define _POSIX_MONOTONIC_CLOCK (-1)
+#endif
+
+typedef puint64 (* PPOSIXTicksFunc) (void);
+
+static PPOSIXTicksFunc pp_time_profiler_ticks_func = NULL;
+
+#if (_POSIX_MONOTONIC_CLOCK >= 0) || defined (P_OS_IRIX)
+static puint64 pp_time_profiler_get_ticks_clock ();
+#endif
+
+static puint64 pp_time_profiler_get_ticks_gtod ();
+
+#if (_POSIX_MONOTONIC_CLOCK >= 0) || defined (P_OS_IRIX)
+static puint64
+pp_time_profiler_get_ticks_clock ()
+{
+ struct timespec ts;
+
+#ifdef P_OS_IRIX
+ if (P_UNLIKELY (clock_gettime (CLOCK_SGI_CYCLE, &ts) != 0)) {
+#else
+ if (P_UNLIKELY (clock_gettime (CLOCK_MONOTONIC, &ts) != 0)) {
+#endif
+ P_ERROR ("PTimeProfiler::pp_time_profiler_get_ticks_clock: clock_gettime() failed");
+ return pp_time_profiler_get_ticks_gtod ();
+ } else
+ return (puint64) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
+}
+#endif
+
+static puint64
+pp_time_profiler_get_ticks_gtod ()
+{
+ struct timeval tv;
+
+ if (P_UNLIKELY (gettimeofday (&tv, NULL) != 0)) {
+ P_ERROR ("PTimeProfiler::pp_time_profiler_get_ticks_gtod: gettimeofday() failed");
+ return 0;
+ }
+
+ return (puint64) (tv.tv_sec * 1000000 + tv.tv_usec);
+}
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ return pp_time_profiler_ticks_func ();
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return pp_time_profiler_ticks_func () - profiler->counter;
+}
+
+void
+p_time_profiler_init (void)
+{
+#if defined (P_OS_IRIX) || (_POSIX_MONOTONIC_CLOCK > 0)
+ pp_time_profiler_ticks_func = (PPOSIXTicksFunc) pp_time_profiler_get_ticks_clock;
+#elif (_POSIX_MONOTONIC_CLOCK == 0) && defined (_SC_MONOTONIC_CLOCK)
+ if (P_LIKELY (sysconf (_SC_MONOTONIC_CLOCK) > 0))
+ pp_time_profiler_ticks_func = (PPOSIXTicksFunc) pp_time_profiler_get_ticks_clock;
+ else
+ pp_time_profiler_ticks_func = (PPOSIXTicksFunc) pp_time_profiler_get_ticks_gtod;
+#else
+ pp_time_profiler_ticks_func = (PPOSIXTicksFunc) pp_time_profiler_get_ticks_gtod;
+#endif
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+ pp_time_profiler_ticks_func = NULL;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-private.h b/3rdparty/plibsys/src/ptimeprofiler-private.h
new file mode 100644
index 0000000..c7c250d
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-private.h
@@ -0,0 +1,45 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTIMEPROFILER_PRIVATE_H
+#define PLIBSYS_HEADER_PTIMEPROFILER_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+
+P_BEGIN_DECLS
+
+/** Time profiler opaque data structure. */
+struct PTimeProfiler_ {
+ puint64 counter; /**< Ticks counter. */
+};
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTIMEPROFILER_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/ptimeprofiler-solaris.c b/3rdparty/plibsys/src/ptimeprofiler-solaris.c
new file mode 100644
index 0000000..5832614
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-solaris.c
@@ -0,0 +1,53 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ return (puint64) gethrtime ();
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return (((puint64) gethrtime ()) - profiler->counter) / 1000;
+}
+
+void
+p_time_profiler_init (void)
+{
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler-win.c b/3rdparty/plibsys/src/ptimeprofiler-win.c
new file mode 100644
index 0000000..22ee72f
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler-win.c
@@ -0,0 +1,169 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* https://msdn.microsoft.com/ru-ru/library/windows/desktop/dn553408(v=vs.85).aspx */
+
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+#include <time.h>
+
+#if PLIBSYS_HAS_LLDIV
+# include <stdlib.h>
+#endif
+
+typedef puint64 (WINAPI * PWin32TicksFunc) (void);
+typedef puint64 (* PWin32ElapsedFunc) (puint64 last_counter);
+
+static PWin32TicksFunc pp_time_profiler_ticks_func = NULL;
+static PWin32ElapsedFunc pp_time_profiler_elapsed_func = NULL;
+static puint64 pp_time_profiler_freq = 1;
+
+static puint64 WINAPI pp_time_profiler_get_hr_ticks (void);
+static puint64 pp_time_profiler_elapsed_hr (puint64 last_counter);
+static puint64 pp_time_profiler_elapsed_tick64 (puint64 last_counter);
+static puint64 pp_time_profiler_elapsed_tick (puint64 last_counter);
+
+static puint64 WINAPI
+pp_time_profiler_get_hr_ticks (void)
+{
+ LARGE_INTEGER tcounter;
+
+ if (P_UNLIKELY (QueryPerformanceCounter (&tcounter) == FALSE)) {
+ P_ERROR ("PTimeProfiler::pp_time_profiler_get_hr_ticks: QueryPerformanceCounter() failed");
+ tcounter.QuadPart = 0;
+ }
+
+ return (puint64) tcounter.QuadPart;
+}
+
+static puint64
+pp_time_profiler_elapsed_hr (puint64 last_counter)
+{
+ puint64 ticks;
+#ifdef PLIBSYS_HAS_LLDIV
+ lldiv_t ldres;
+#endif
+ puint64 quot;
+ puint64 rem;
+
+ ticks = pp_time_profiler_ticks_func () - last_counter;
+
+#ifdef PLIBSYS_HAS_LLDIV
+ ldres = lldiv ((long long) ticks, (long long) pp_time_profiler_freq);
+
+ quot = ldres.quot;
+ rem = ldres.rem;
+#else
+ quot = ticks / pp_time_profiler_freq;
+ rem = ticks % pp_time_profiler_freq;
+#endif
+
+ return (puint64) (quot * 1000000 + (rem * 1000000) / pp_time_profiler_freq);
+}
+
+static puint64
+pp_time_profiler_elapsed_tick64 (puint64 last_counter)
+{
+ return (pp_time_profiler_ticks_func () - last_counter) * 1000;
+}
+
+static puint64
+pp_time_profiler_elapsed_tick (puint64 last_counter)
+{
+ puint64 val;
+ puint64 high_bit;
+
+ high_bit = 0;
+ val = pp_time_profiler_ticks_func ();
+
+ if (P_UNLIKELY (val < last_counter))
+ high_bit = 1;
+
+ return ((val | (high_bit << 32)) - last_counter) * 1000;
+}
+
+puint64
+p_time_profiler_get_ticks_internal ()
+{
+ return pp_time_profiler_ticks_func ();
+}
+
+puint64
+p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler)
+{
+ return pp_time_profiler_elapsed_func (profiler->counter);
+}
+
+void
+p_time_profiler_init (void)
+{
+ LARGE_INTEGER tcounter;
+ HMODULE hmodule;
+ pboolean has_qpc;
+
+ has_qpc = (QueryPerformanceCounter (&tcounter) != 0 && tcounter.QuadPart != 0) ? TRUE : FALSE;
+
+ if (has_qpc == TRUE) {
+ if (P_UNLIKELY (QueryPerformanceFrequency (&tcounter) == 0)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_init: QueryPerformanceFrequency() failed");
+ has_qpc = FALSE;
+ } else {
+ pp_time_profiler_freq = (puint64) (tcounter.QuadPart);
+ pp_time_profiler_ticks_func = (PWin32TicksFunc) pp_time_profiler_get_hr_ticks;
+ pp_time_profiler_elapsed_func = (PWin32ElapsedFunc) pp_time_profiler_elapsed_hr;
+ }
+ }
+
+ if (P_UNLIKELY (has_qpc == FALSE)) {
+ hmodule = GetModuleHandleA ("kernel32.dll");
+
+ if (P_UNLIKELY (hmodule == NULL)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_init: failed to load kernel32.dll module");
+ return;
+ }
+
+ pp_time_profiler_ticks_func = (PWin32TicksFunc) GetProcAddress (hmodule, "GetTickCount64");
+ pp_time_profiler_elapsed_func = (PWin32ElapsedFunc) pp_time_profiler_elapsed_tick64;
+
+ if (P_UNLIKELY (pp_time_profiler_ticks_func == NULL)) {
+ pp_time_profiler_ticks_func = (PWin32TicksFunc) GetProcAddress (hmodule, "GetTickCount");
+ pp_time_profiler_elapsed_func = (PWin32ElapsedFunc) pp_time_profiler_elapsed_tick;
+ }
+
+ if (P_UNLIKELY (pp_time_profiler_ticks_func == NULL)) {
+ P_ERROR ("PTimeProfiler::p_time_profiler_init: no reliable tick counter");
+ pp_time_profiler_elapsed_func = NULL;
+ }
+ }
+}
+
+void
+p_time_profiler_shutdown (void)
+{
+ pp_time_profiler_freq = 1;
+ pp_time_profiler_ticks_func = NULL;
+ pp_time_profiler_elapsed_func = NULL;
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler.c b/3rdparty/plibsys/src/ptimeprofiler.c
new file mode 100644
index 0000000..a23ea54
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler.c
@@ -0,0 +1,70 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "ptimeprofiler.h"
+#include "ptimeprofiler-private.h"
+
+extern puint64 p_time_profiler_get_ticks_internal (void);
+extern puint64 p_time_profiler_elapsed_usecs_internal (const PTimeProfiler *profiler);
+
+P_LIB_API PTimeProfiler *
+p_time_profiler_new ()
+{
+ PTimeProfiler *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PTimeProfiler))) == NULL)) {
+ P_ERROR ("PTimeProfiler: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->counter = p_time_profiler_get_ticks_internal ();
+
+ return ret;
+}
+
+P_LIB_API void
+p_time_profiler_reset (PTimeProfiler *profiler)
+{
+ if (P_UNLIKELY (profiler == NULL))
+ return;
+
+ profiler->counter = p_time_profiler_get_ticks_internal ();
+}
+
+P_LIB_API puint64
+p_time_profiler_elapsed_usecs (const PTimeProfiler *profiler)
+{
+ if (P_UNLIKELY (profiler == NULL))
+ return 0;
+
+ return p_time_profiler_elapsed_usecs_internal (profiler);
+}
+
+P_LIB_API void
+p_time_profiler_free (PTimeProfiler *profiler)
+{
+ p_free (profiler);
+}
diff --git a/3rdparty/plibsys/src/ptimeprofiler.h b/3rdparty/plibsys/src/ptimeprofiler.h
new file mode 100644
index 0000000..6dbf4ab
--- /dev/null
+++ b/3rdparty/plibsys/src/ptimeprofiler.h
@@ -0,0 +1,93 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file ptimeprofiler.h
+ * @brief Time profiler
+ * @author Alexander Saprykin
+ *
+ * #PTimeProfiler acts like a time chronometer: in any moment of time you can
+ * make a time slice to see how much time elapsed since the last slice or timer
+ * start.
+ *
+ * This profiler is useful to gather information about execution time for calls
+ * or parts of the code. It can help to leverage bottle-necks in your code.
+ *
+ * To start using a profiler create a new one with p_time_profiler_new() call
+ * and p_time_profiler_elapsed_usecs() to get elapsed time since the creation.
+ * If you need to reset a profiler use p_time_profiler_reset(). Remove a
+ * profiler with p_time_profiler_free().
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTIMEPROFILER_H
+#define PLIBSYS_HEADER_PTIMEPROFILER_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Time profiler opaque data structure. */
+typedef struct PTimeProfiler_ PTimeProfiler;
+
+/**
+ * @brief Creates a new #PTimeProfiler object.
+ * @return Pointer to a newly created #PTimeProfiler object.
+ * @since 0.0.1
+ */
+P_LIB_API PTimeProfiler * p_time_profiler_new (void);
+
+/**
+ * @brief Resets the #PTimeProfiler's internal counter to zero.
+ * @param profiler Time profiler to reset.
+ * @since 0.0.1
+ *
+ * After a reset the time profiler begins to count elapsed time from that moment
+ * of time.
+ */
+P_LIB_API void p_time_profiler_reset (PTimeProfiler * profiler);
+
+/**
+ * @brief Calculates elapsed time since the last reset or creation.
+ * @param profiler Time profiler to calculate elapsed time for.
+ * @return Microseconds elapsed since the last reset or creation.
+ * @since 0.0.1
+ */
+P_LIB_API puint64 p_time_profiler_elapsed_usecs (const PTimeProfiler * profiler);
+
+/**
+ * @brief Frees #PTimeProfiler object.
+ * @param profiler #PTimeProfiler to free.
+ * @since 0.0.1
+ */
+P_LIB_API void p_time_profiler_free (PTimeProfiler * profiler);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTIMEPROFILER_H */
diff --git a/3rdparty/plibsys/src/ptree-avl.c b/3rdparty/plibsys/src/ptree-avl.c
new file mode 100644
index 0000000..c100e5c
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-avl.c
@@ -0,0 +1,481 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "ptree-avl.h"
+
+typedef struct PTreeAVLNode_ {
+ struct PTreeBaseNode_ base;
+ struct PTreeAVLNode_ *parent;
+ pint balance_factor;
+} PTreeAVLNode;
+
+static void pp_tree_avl_rotate_left (PTreeAVLNode *node, PTreeBaseNode **root);
+static void pp_tree_avl_rotate_right (PTreeAVLNode *node, PTreeBaseNode **root);
+static void pp_tree_avl_rotate_left_right (PTreeAVLNode *node, PTreeBaseNode **root);
+static void pp_tree_avl_rotate_right_left (PTreeAVLNode *node, PTreeBaseNode **root);
+static void pp_tree_avl_balance_insert (PTreeAVLNode *node, PTreeBaseNode **root);
+static void pp_tree_avl_balance_remove (PTreeAVLNode *node, PTreeBaseNode **root);
+
+static void
+pp_tree_avl_rotate_left (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ node->parent->base.right = node->base.left;
+
+ if (node->base.left != NULL)
+ ((PTreeAVLNode *) node->base.left)->parent = (PTreeAVLNode *) node->parent;
+
+ node->base.left = (PTreeBaseNode *) node->parent;
+ node->parent = ((PTreeAVLNode *) node->base.left)->parent;
+ ((PTreeAVLNode *) node->base.left)->parent = node;
+
+ if (P_LIKELY (node->parent != NULL)) {
+ if (node->parent->base.left == node->base.left)
+ node->parent->base.left = (PTreeBaseNode *) node;
+ else
+ node->parent->base.right = (PTreeBaseNode *) node;
+ } else
+ *root = (PTreeBaseNode *) node;
+
+ /* Restore balance factor */
+ ((PTreeAVLNode *) node)->balance_factor +=1;
+ ((PTreeAVLNode *) node->base.left)->balance_factor = -((PTreeAVLNode *) node)->balance_factor;
+}
+
+static void
+pp_tree_avl_rotate_right (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ node->parent->base.left = node->base.right;
+
+ if (node->base.right != NULL)
+ ((PTreeAVLNode *) node->base.right)->parent = (PTreeAVLNode *) node->parent;
+
+ node->base.right = (PTreeBaseNode *) node->parent;
+ node->parent = ((PTreeAVLNode *) node->base.right)->parent;
+ ((PTreeAVLNode *) node->base.right)->parent = node;
+
+ if (P_LIKELY (node->parent != NULL)) {
+ if (node->parent->base.left == node->base.right)
+ node->parent->base.left = (PTreeBaseNode *) node;
+ else
+ node->parent->base.right = (PTreeBaseNode *) node;
+ } else
+ *root = (PTreeBaseNode *) node;
+
+ /* Restore balance factor */
+ ((PTreeAVLNode *) node)->balance_factor -= 1;
+ ((PTreeAVLNode *) node->base.right)->balance_factor = -((PTreeAVLNode *) node)->balance_factor;
+}
+
+static void
+pp_tree_avl_rotate_left_right (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ PTreeAVLNode *tmp_node;
+
+ tmp_node = (PTreeAVLNode *) node->base.right;
+ node->base.right = tmp_node->base.left;
+
+ if (node->base.right != NULL)
+ ((PTreeAVLNode *) node->base.right)->parent = node;
+
+ tmp_node->parent = node->parent->parent;
+
+ if (P_LIKELY (tmp_node->parent != NULL)) {
+ if (tmp_node->parent->base.left == (PTreeBaseNode *) node->parent)
+ tmp_node->parent->base.left = (PTreeBaseNode *) tmp_node;
+ else
+ tmp_node->parent->base.right = (PTreeBaseNode *) tmp_node;
+ } else
+ *root = (PTreeBaseNode *) tmp_node;
+
+ node->parent->base.left = tmp_node->base.right;
+
+ if (node->parent->base.left != NULL)
+ ((PTreeAVLNode *) node->parent->base.left)->parent = node->parent;
+
+ tmp_node->base.right = (PTreeBaseNode *) node->parent;
+ ((PTreeAVLNode *) tmp_node->base.right)->parent = tmp_node;
+
+ tmp_node->base.left = (PTreeBaseNode *) node;
+ node->parent = tmp_node;
+
+ /* Restore balance factor */
+ if (tmp_node->balance_factor == 1) {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 0;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = -1;
+ } else if (tmp_node->balance_factor == -1) {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 1;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = 0;
+ } else {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 0;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = 0;
+ }
+
+ tmp_node->balance_factor = 0;
+}
+
+static void
+pp_tree_avl_rotate_right_left (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ PTreeAVLNode *tmp_node;
+
+ tmp_node = (PTreeAVLNode *) node->base.left;
+ node->base.left = tmp_node->base.right;
+
+ if (node->base.left != NULL)
+ ((PTreeAVLNode *) node->base.left)->parent = node;
+
+ tmp_node->parent = node->parent->parent;
+
+ if (P_LIKELY (tmp_node->parent != NULL)) {
+ if (tmp_node->parent->base.left == (PTreeBaseNode *) node->parent)
+ tmp_node->parent->base.left = (PTreeBaseNode *) tmp_node;
+ else
+ tmp_node->parent->base.right = (PTreeBaseNode *) tmp_node;
+ } else
+ *root = (PTreeBaseNode *) tmp_node;
+
+ node->parent->base.right = tmp_node->base.left;
+
+ if (node->parent->base.right != NULL)
+ ((PTreeAVLNode *) node->parent->base.right)->parent = node->parent;
+
+ tmp_node->base.left = (PTreeBaseNode *) node->parent;
+ ((PTreeAVLNode *) tmp_node->base.left)->parent = tmp_node;
+
+ tmp_node->base.right = (PTreeBaseNode *) node;
+ node->parent = tmp_node;
+
+ /* Restore balance factor */
+ if (tmp_node->balance_factor == 1) {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 0;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = -1;
+ } else if (tmp_node->balance_factor == -1) {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 1;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = 0;
+ } else {
+ ((PTreeAVLNode *) tmp_node->base.left)->balance_factor = 0;
+ ((PTreeAVLNode *) tmp_node->base.right)->balance_factor = 0;
+ }
+
+ tmp_node->balance_factor = 0;
+}
+
+static void
+pp_tree_avl_balance_insert (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ PTreeAVLNode *parent;
+
+ while (TRUE) {
+ parent = node->parent;
+
+ if (P_UNLIKELY (parent == NULL))
+ break;
+
+ if (parent->base.left == (PTreeBaseNode *) node) {
+ if (parent->balance_factor == 1) {
+ if (node->balance_factor == -1)
+ /* Case 1: Left-right rotate
+ *
+ * (5) (4)
+ * / \ / \
+ * (3) A --> (3) (5)
+ * / \ / \ / \
+ * B (4) B C D A
+ * / \
+ * C D
+ */
+ pp_tree_avl_rotate_left_right (node, root);
+ else
+ /* Case 2: Right rotate
+ *
+ * (5) (4)
+ * / \ / \
+ * (4) A --> (3) (5)
+ * / \ / \ / \
+ * (3) B C D B A
+ * / \
+ * C D
+ */
+ pp_tree_avl_rotate_right (node, root);
+
+ break;
+ } else if (parent->balance_factor == -1) {
+ /* Case 3: Increase parent balance factor */
+ parent->balance_factor = 0;
+ break;
+ } else
+ /* Case 4: Increase parent balance factor */
+ parent->balance_factor = 1;
+ } else {
+ if (parent->balance_factor == -1) {
+ if (node->balance_factor == 1)
+ /* Case 1: Right-left rotate
+ *
+ * (3) (4)
+ * / \ / \
+ * A (5) --> (3) (5)
+ * / \ / \ / \
+ * (4) B A C D B
+ * / \
+ * C D
+ */
+ pp_tree_avl_rotate_right_left (node, root);
+ else
+ /* Case 2: Left rotate
+ *
+ * (3) (4)
+ * / \ / \
+ * A (4) --> (3) (5)
+ * / \ / \ / \
+ * B (5) A B C D
+ * / \
+ * C D
+ */
+ pp_tree_avl_rotate_left (node, root);
+
+ break;
+ } else if (parent->balance_factor == 1) {
+ /* Case 3: Decrease parent balance factor */
+ parent->balance_factor = 0;
+ break;
+ } else
+ /* Case 4: Decrease parent balance factor */
+ parent->balance_factor = -1;
+ }
+
+ node = node->parent;
+ }
+}
+
+static void
+pp_tree_avl_balance_remove (PTreeAVLNode *node, PTreeBaseNode **root)
+{
+ PTreeAVLNode *parent;
+ PTreeAVLNode *sibling;
+ pint sibling_balance;
+
+ while (TRUE) {
+ parent = node->parent;
+
+ if (P_UNLIKELY (parent == NULL))
+ break;
+
+ if (parent->base.left == (PTreeBaseNode *) node) {
+ if (parent->balance_factor == -1) {
+ sibling = (PTreeAVLNode *) parent->base.right;
+ sibling_balance = sibling->balance_factor;
+
+ if (sibling->balance_factor == 1)
+ /* Case 1 */
+ pp_tree_avl_rotate_right_left (sibling, root);
+ else
+ /* Case 2 */
+ pp_tree_avl_rotate_left (sibling, root);
+
+ node = parent;
+
+ if (sibling_balance == 0)
+ break;
+ } else if (parent->balance_factor == 0) {
+ /* Case 3 */
+ parent->balance_factor = -1;
+ break;
+ } else
+ /* Case 4 */
+ parent->balance_factor = 0;
+ } else {
+ if (parent->balance_factor == 1) {
+ sibling = (PTreeAVLNode *) parent->base.left;
+ sibling_balance = sibling->balance_factor;
+
+ if (sibling->balance_factor == -1)
+ /* Case 1 */
+ pp_tree_avl_rotate_left_right (sibling, root);
+ else
+ /* Case 2 */
+ pp_tree_avl_rotate_right (sibling, root);
+
+ node = parent;
+
+ if (sibling_balance == 0)
+ break;
+ } else if (parent->balance_factor == 0) {
+ /* Case 3 */
+ parent->balance_factor = 1;
+ break;
+ } else
+ /* Case 4 */
+ parent->balance_factor = 0;
+ }
+
+ node = node->parent;
+ }
+}
+
+pboolean
+p_tree_avl_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value)
+{
+ PTreeBaseNode **cur_node;
+ PTreeBaseNode *parent_node;
+ pint cmp_result;
+
+ cur_node = root_node;
+ parent_node = *root_node;
+
+ /* Find where to insert the node */
+ while (*cur_node != NULL) {
+ cmp_result = compare_func (key, (*cur_node)->key, data);
+
+ if (cmp_result < 0) {
+ parent_node = *cur_node;
+ cur_node = &(*cur_node)->left;
+ } else if (cmp_result > 0) {
+ parent_node = *cur_node;
+ cur_node = &(*cur_node)->right;
+ } else
+ break;
+ }
+
+ /* If we have existing one - replace a key-value pair */
+ if (*cur_node != NULL) {
+ if (key_destroy_func != NULL)
+ key_destroy_func ((*cur_node)->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func ((*cur_node)->value);
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((*cur_node = p_malloc0 (sizeof (PTreeAVLNode))) == NULL))
+ return FALSE;
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ ((PTreeAVLNode *) *cur_node)->balance_factor = 0;
+ ((PTreeAVLNode *) *cur_node)->parent = (PTreeAVLNode *) parent_node;
+
+ /* Balance the tree */
+ pp_tree_avl_balance_insert (((PTreeAVLNode *) *cur_node), root_node);
+
+ return TRUE;
+}
+
+pboolean
+p_tree_avl_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key)
+{
+ PTreeBaseNode *cur_node;
+ PTreeBaseNode *prev_node;
+ PTreeBaseNode *child_node;
+ PTreeAVLNode *child_parent;
+ pint cmp_result;
+
+ cur_node = *root_node;
+
+ while (cur_node != NULL) {
+ cmp_result = compare_func (key, cur_node->key, data);
+
+ if (cmp_result < 0)
+ cur_node = cur_node->left;
+ else if (cmp_result > 0)
+ cur_node = cur_node->right;
+ else
+ break;
+ }
+
+ if (P_UNLIKELY (cur_node == NULL))
+ return FALSE;
+
+ if (cur_node->left != NULL && cur_node->right != NULL) {
+ prev_node = cur_node->left;
+
+ while (prev_node->right != NULL)
+ prev_node = prev_node->right;
+
+ cur_node->key = prev_node->key;
+ cur_node->value = prev_node->value;
+
+ /* Mark node for removal */
+ cur_node = prev_node;
+ }
+
+ child_node = cur_node->left == NULL ? cur_node->right : cur_node->left;
+
+ if (child_node == NULL)
+ pp_tree_avl_balance_remove ((PTreeAVLNode *) cur_node, root_node);
+
+ /* Replace node with its child */
+ if (P_UNLIKELY (cur_node == *root_node)) {
+ *root_node = child_node;
+ child_parent = NULL;
+ } else {
+ child_parent = ((PTreeAVLNode *) cur_node)->parent;
+
+ if (child_parent->base.left == cur_node)
+ child_parent->base.left = child_node;
+ else
+ child_parent->base.right = child_node;
+ }
+
+ if (child_node != NULL) {
+ ((PTreeAVLNode *) child_node)->parent = child_parent;
+
+ /* Balance the tree */
+ pp_tree_avl_balance_remove ((PTreeAVLNode *) child_node, root_node);
+ }
+
+ /* Free unused node */
+ if (key_destroy_func != NULL)
+ key_destroy_func (cur_node->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func (cur_node->value);
+
+ p_free (cur_node);
+
+ return TRUE;
+}
+
+void
+p_tree_avl_node_free (PTreeBaseNode *node)
+{
+ p_free (node);
+}
diff --git a/3rdparty/plibsys/src/ptree-avl.h b/3rdparty/plibsys/src/ptree-avl.h
new file mode 100644
index 0000000..dccba2a
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-avl.h
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTREEAVL_H
+#define PLIBSYS_HEADER_PTREEAVL_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+#include "ptree-private.h"
+
+P_BEGIN_DECLS
+
+pboolean p_tree_avl_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value);
+
+pboolean p_tree_avl_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key);
+
+void p_tree_avl_node_free (PTreeBaseNode *node);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTREEAVL_H */
diff --git a/3rdparty/plibsys/src/ptree-bst.c b/3rdparty/plibsys/src/ptree-bst.c
new file mode 100644
index 0000000..02fae28
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-bst.c
@@ -0,0 +1,140 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "ptree-bst.h"
+
+pboolean
+p_tree_bst_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value)
+{
+ PTreeBaseNode **cur_node;
+ pint cmp_result;
+
+ cur_node = root_node;
+
+ while (*cur_node != NULL) {
+ cmp_result = compare_func (key, (*cur_node)->key, data);
+
+ if (cmp_result < 0)
+ cur_node = &(*cur_node)->left;
+ else if (cmp_result > 0)
+ cur_node = &(*cur_node)->right;
+ else
+ break;
+ }
+
+ if ((*cur_node) == NULL) {
+ if (P_UNLIKELY ((*cur_node = p_malloc0 (sizeof (PTreeBaseNode))) == NULL))
+ return FALSE;
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ return TRUE;
+ } else {
+ if (key_destroy_func != NULL)
+ key_destroy_func ((*cur_node)->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func ((*cur_node)->value);
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ return FALSE;
+ }
+}
+
+pboolean
+p_tree_bst_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key)
+{
+ PTreeBaseNode *cur_node;
+ PTreeBaseNode *prev_node;
+ PTreeBaseNode **node_pointer;
+ pint cmp_result;
+
+ cur_node = *root_node;
+ node_pointer = root_node;
+
+ while (cur_node != NULL) {
+ cmp_result = compare_func (key, cur_node->key, data);
+
+ if (cmp_result < 0) {
+ node_pointer = &cur_node->left;
+ cur_node = cur_node->left;
+ } else if (cmp_result > 0) {
+ node_pointer = &cur_node->right;
+ cur_node = cur_node->right;
+ } else
+ break;
+ }
+
+ if (P_UNLIKELY (cur_node == NULL))
+ return FALSE;
+
+ if (cur_node->left != NULL && cur_node->right != NULL) {
+ node_pointer = &cur_node->left;
+ prev_node = cur_node->left;
+
+ while (prev_node->right != NULL) {
+ node_pointer = &prev_node->right;
+ prev_node = prev_node->right;
+ }
+
+ cur_node->key = prev_node->key;
+ cur_node->value = prev_node->value;
+
+ cur_node = prev_node;
+ }
+
+ *node_pointer = cur_node->left == NULL ? cur_node->right : cur_node->left;
+
+ if (key_destroy_func != NULL)
+ key_destroy_func (cur_node->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func (cur_node->value);
+
+ p_free (cur_node);
+
+ return TRUE;
+}
+
+void
+p_tree_bst_node_free (PTreeBaseNode *node)
+{
+ p_free (node);
+}
diff --git a/3rdparty/plibsys/src/ptree-bst.h b/3rdparty/plibsys/src/ptree-bst.h
new file mode 100644
index 0000000..a0ac18d
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-bst.h
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTREEBST_H
+#define PLIBSYS_HEADER_PTREEBST_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+#include "ptree-private.h"
+
+P_BEGIN_DECLS
+
+pboolean p_tree_bst_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value);
+
+pboolean p_tree_bst_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key);
+
+void p_tree_bst_node_free (PTreeBaseNode *node);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTREEBST_H */
diff --git a/3rdparty/plibsys/src/ptree-private.h b/3rdparty/plibsys/src/ptree-private.h
new file mode 100644
index 0000000..5af1a67
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-private.h
@@ -0,0 +1,48 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTREE_PRIVATE_H
+#define PLIBSYS_HEADER_PTREE_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+
+P_BEGIN_DECLS
+
+/** Base tree leaf structure. */
+typedef struct PTreeBaseNode_ {
+ struct PTreeBaseNode_ *left; /**< Left child. */
+ struct PTreeBaseNode_ *right; /**< Right child. */
+ ppointer key; /**< Node key. */
+ ppointer value; /**< Node value. */
+} PTreeBaseNode;
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTREE_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/ptree-rb.c b/3rdparty/plibsys/src/ptree-rb.c
new file mode 100644
index 0000000..53c7b09
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-rb.c
@@ -0,0 +1,484 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ * Illustrations have been taken from the Linux kernel rbtree.c
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "ptree-rb.h"
+
+typedef enum PTreeRBColor_ {
+ P_TREE_RB_COLOR_RED = 0x01,
+ P_TREE_RB_COLOR_BLACK = 0x02
+} PTreeRBColor;
+
+typedef struct PTreeRBNode_ {
+ struct PTreeBaseNode_ base;
+ struct PTreeRBNode_ *parent;
+ PTreeRBColor color;
+} PTreeRBNode;
+
+static pboolean pp_tree_rb_is_black (PTreeRBNode *node);
+static pboolean pp_tree_rb_is_red (PTreeRBNode *node);
+static PTreeRBNode * pp_tree_rb_get_gparent (PTreeRBNode *node);
+static PTreeRBNode * pp_tree_rb_get_uncle (PTreeRBNode *node);
+static PTreeRBNode * pp_tree_rb_get_sibling (PTreeRBNode *node);
+static void pp_tree_rb_rotate_left (PTreeRBNode *node, PTreeBaseNode **root);
+static void pp_tree_rb_rotate_right (PTreeRBNode *node, PTreeBaseNode **root);
+static void pp_tree_rb_balance_insert (PTreeRBNode *node, PTreeBaseNode **root);
+static void pp_tree_rb_balance_remove (PTreeRBNode *node, PTreeBaseNode **root);
+
+static pboolean
+pp_tree_rb_is_black (PTreeRBNode *node)
+{
+ if (node == NULL)
+ return TRUE;
+
+ return ((node->color) & P_TREE_RB_COLOR_BLACK) > 0 ? TRUE : FALSE;
+}
+
+static pboolean
+pp_tree_rb_is_red (PTreeRBNode *node)
+{
+ return ((node->color) & P_TREE_RB_COLOR_RED) > 0 ? TRUE : FALSE;
+}
+
+static PTreeRBNode *
+pp_tree_rb_get_gparent (PTreeRBNode *node)
+{
+ return node->parent->parent;
+}
+
+static PTreeRBNode *
+pp_tree_rb_get_uncle (PTreeRBNode *node)
+{
+ PTreeRBNode *gparent = pp_tree_rb_get_gparent (node);
+
+ if ((PTreeRBNode *) gparent->base.left == node->parent)
+ return (PTreeRBNode *) gparent->base.right;
+ else
+ return (PTreeRBNode *) gparent->base.left;
+}
+
+static PTreeRBNode *
+pp_tree_rb_get_sibling (PTreeRBNode *node)
+{
+ if (node->parent->base.left == (PTreeBaseNode *) node)
+ return (PTreeRBNode *) node->parent->base.right;
+ else
+ return (PTreeRBNode *) node->parent->base.left;
+}
+
+static void
+pp_tree_rb_rotate_left (PTreeRBNode *node, PTreeBaseNode **root)
+{
+ PTreeBaseNode *tmp_node;
+
+ tmp_node = node->base.right;
+
+ if (P_LIKELY (node->parent != NULL)) {
+ if (node->parent->base.left == (PTreeBaseNode *) node)
+ node->parent->base.left = tmp_node;
+ else
+ node->parent->base.right = tmp_node;
+ }
+
+ node->base.right = tmp_node->left;
+
+ if (tmp_node->left != NULL)
+ ((PTreeRBNode *) tmp_node->left)->parent = node;
+
+ tmp_node->left = (PTreeBaseNode *) node;
+ ((PTreeRBNode *) tmp_node)->parent = node->parent;
+ node->parent = (PTreeRBNode *) tmp_node;
+
+ if (P_UNLIKELY (((PTreeRBNode *) tmp_node)->parent == NULL))
+ *root = tmp_node;
+}
+
+static void
+pp_tree_rb_rotate_right (PTreeRBNode *node, PTreeBaseNode **root)
+{
+ PTreeBaseNode *tmp_node;
+
+ tmp_node = node->base.left;
+
+ if (P_LIKELY (node->parent != NULL)) {
+ if (node->parent->base.left == (PTreeBaseNode *) node)
+ node->parent->base.left = tmp_node;
+ else
+ node->parent->base.right = tmp_node;
+ }
+
+ node->base.left = tmp_node->right;
+
+ if (tmp_node->right != NULL)
+ ((PTreeRBNode *) tmp_node->right)->parent = node;
+
+ tmp_node->right = (PTreeBaseNode *) node;
+ ((PTreeRBNode *) tmp_node)->parent = node->parent;
+ node->parent = (PTreeRBNode *) tmp_node;
+
+ if (P_UNLIKELY (((PTreeRBNode *) tmp_node)->parent == NULL))
+ *root = tmp_node;
+}
+
+static void
+pp_tree_rb_balance_insert (PTreeRBNode *node, PTreeBaseNode **root)
+{
+ PTreeRBNode *uncle;
+ PTreeRBNode *gparent;
+
+ while (TRUE) {
+ /* Case 1: We are at the root */
+ if (P_UNLIKELY (node->parent == NULL)) {
+ node->color = P_TREE_RB_COLOR_BLACK;
+ break;
+ }
+
+ /* Case 2: We have a black parent */
+ if (pp_tree_rb_is_black (node->parent) == TRUE)
+ break;
+
+ uncle = pp_tree_rb_get_uncle (node);
+ gparent = pp_tree_rb_get_gparent (node);
+
+ /* Case 3: Both parent and uncle are red, flip colors
+ *
+ * G g
+ * / \ / \
+ * p u --> P U
+ * / /
+ * n n
+ */
+ if (uncle != NULL && pp_tree_rb_is_red (uncle) == TRUE) {
+ node->parent->color = P_TREE_RB_COLOR_BLACK;
+ uncle->color = P_TREE_RB_COLOR_BLACK;
+ gparent->color = P_TREE_RB_COLOR_RED;
+
+ /* Continue iteratively from gparent */
+ node = gparent;
+ continue;
+ }
+
+ if (node->parent == (PTreeRBNode *) gparent->base.left) {
+ if (node == (PTreeRBNode *) node->parent->base.right) {
+ /* Case 4a: Left rotate at parent
+ *
+ * G G
+ * / \ / \
+ * p U --> n U
+ * \ /
+ * n p
+ */
+ pp_tree_rb_rotate_left (node->parent, root);
+
+ node = (PTreeRBNode *) node->base.left;
+ }
+
+ gparent->color = P_TREE_RB_COLOR_RED;
+ node->parent->color = P_TREE_RB_COLOR_BLACK;
+
+ /* Case 5a: Right rotate at gparent
+ *
+ * G P
+ * / \ / \
+ * p U --> n g
+ * / \
+ * n U
+ */
+ pp_tree_rb_rotate_right (gparent, root);
+
+ break;
+ } else {
+ if (node == (PTreeRBNode *) node->parent->base.left) {
+ /* Case 4b: Right rotate at parent */
+ pp_tree_rb_rotate_right (node->parent, root);
+
+ node = (PTreeRBNode *) node->base.right;
+ }
+
+ gparent->color = P_TREE_RB_COLOR_RED;
+ node->parent->color = P_TREE_RB_COLOR_BLACK;
+
+ /* Case 5b: Left rotate at gparent*/
+ pp_tree_rb_rotate_left (gparent, root);
+
+ break;
+ }
+ }
+}
+
+static void
+pp_tree_rb_balance_remove (PTreeRBNode *node, PTreeBaseNode **root)
+{
+ PTreeRBNode *sibling;
+
+ while (TRUE) {
+ /* Case 1: We are at the root */
+ if (P_UNLIKELY (node->parent == NULL))
+ break;
+
+ sibling = pp_tree_rb_get_sibling (node);
+
+ if (pp_tree_rb_is_red (sibling) == TRUE) {
+ /*
+ * Case 2: Left (right) rotate at parent
+ *
+ * P S
+ * / \ / \
+ * N s --> p Sr
+ * / \ / \
+ * Sl Sr N Sl
+ */
+ node->parent->color = P_TREE_RB_COLOR_RED;
+ sibling->color = P_TREE_RB_COLOR_BLACK;
+
+ if ((PTreeBaseNode *) node == node->parent->base.left)
+ pp_tree_rb_rotate_left (node->parent, root);
+ else
+ pp_tree_rb_rotate_right (node->parent, root);
+
+ sibling = pp_tree_rb_get_sibling (node);
+ }
+
+ /*
+ * Case 3: Sibling (parent) color flip
+ *
+ * (p) (p)
+ * / \ / \
+ * N S --> N s
+ * / \ / \
+ * Sl Sr Sl Sr
+ */
+ if (pp_tree_rb_is_black ((PTreeRBNode *) sibling->base.left) == TRUE &&
+ pp_tree_rb_is_black ((PTreeRBNode *) sibling->base.right) == TRUE) {
+ sibling->color = P_TREE_RB_COLOR_RED;
+
+ if (pp_tree_rb_is_black (node->parent) == TRUE) {
+ node = node->parent;
+ continue;
+ } else {
+ node->parent->color = P_TREE_RB_COLOR_BLACK;
+ break;
+ }
+ }
+
+ /*
+ * Case 4: Right (left) rotate at sibling
+ *
+ * (p) (p)
+ * / \ / \
+ * N S --> N Sl
+ * / \ \
+ * sl Sr s
+ * \
+ * Sr
+ */
+ if ((PTreeBaseNode *) node == node->parent->base.left &&
+ pp_tree_rb_is_black ((PTreeRBNode *) sibling->base.right) == TRUE) {
+ sibling->color = P_TREE_RB_COLOR_RED;
+ ((PTreeRBNode *) sibling->base.left)->color = P_TREE_RB_COLOR_BLACK;
+
+ pp_tree_rb_rotate_right (sibling, root);
+
+ sibling = pp_tree_rb_get_sibling (node);
+ } else if ((PTreeBaseNode *) node == node->parent->base.right &&
+ pp_tree_rb_is_black ((PTreeRBNode *) sibling->base.left) == TRUE) {
+ sibling->color = P_TREE_RB_COLOR_RED;
+ ((PTreeRBNode *) sibling->base.right)->color = P_TREE_RB_COLOR_BLACK;
+
+ pp_tree_rb_rotate_left (sibling, root);
+
+ sibling = pp_tree_rb_get_sibling (node);
+ }
+
+ /*
+ * Case 5: Left (right) rotate at parent and color flips
+ *
+ * (p) (s)
+ * / \ / \
+ * N S --> P Sr
+ * / \ / \
+ * (sl) sr N (sl)
+ */
+ sibling->color = node->parent->color;
+ node->parent->color = P_TREE_RB_COLOR_BLACK;
+
+ if ((PTreeBaseNode *) node == node->parent->base.left) {
+ ((PTreeRBNode *) sibling->base.right)->color = P_TREE_RB_COLOR_BLACK;
+ pp_tree_rb_rotate_left (node->parent, root);
+ } else {
+ ((PTreeRBNode *) sibling->base.left)->color = P_TREE_RB_COLOR_BLACK;
+ pp_tree_rb_rotate_right (node->parent, root);
+ }
+
+ break;
+ }
+}
+
+pboolean
+p_tree_rb_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value)
+{
+ PTreeBaseNode **cur_node;
+ PTreeBaseNode *parent_node;
+ pint cmp_result;
+
+ cur_node = root_node;
+ parent_node = *root_node;
+
+ /* Find where to insert the node */
+ while (*cur_node != NULL) {
+ cmp_result = compare_func (key, (*cur_node)->key, data);
+
+ if (cmp_result < 0) {
+ parent_node = *cur_node;
+ cur_node = &(*cur_node)->left;
+ } else if (cmp_result > 0) {
+ parent_node = *cur_node;
+ cur_node = &(*cur_node)->right;
+ } else
+ break;
+ }
+
+ /* If we have existing one - replace a key-value pair */
+ if (*cur_node != NULL) {
+ if (key_destroy_func != NULL)
+ key_destroy_func ((*cur_node)->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func ((*cur_node)->value);
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ return FALSE;
+ }
+
+ if (P_UNLIKELY ((*cur_node = p_malloc0 (sizeof (PTreeRBNode))) == NULL))
+ return FALSE;
+
+ (*cur_node)->key = key;
+ (*cur_node)->value = value;
+
+ ((PTreeRBNode *) *cur_node)->color = P_TREE_RB_COLOR_RED;
+ ((PTreeRBNode *) *cur_node)->parent = (PTreeRBNode *) parent_node;
+
+ /* Balance the tree */
+ pp_tree_rb_balance_insert ((PTreeRBNode *) *cur_node, root_node);
+
+ return TRUE;
+}
+
+pboolean
+p_tree_rb_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key)
+{
+ PTreeBaseNode *cur_node;
+ PTreeBaseNode *prev_node;
+ PTreeBaseNode *child_node;
+ PTreeRBNode *child_parent;
+ pint cmp_result;
+
+ cur_node = *root_node;
+
+ while (cur_node != NULL) {
+ cmp_result = compare_func (key, cur_node->key, data);
+
+ if (cmp_result < 0)
+ cur_node = cur_node->left;
+ else if (cmp_result > 0)
+ cur_node = cur_node->right;
+ else
+ break;
+ }
+
+ if (P_UNLIKELY (cur_node == NULL))
+ return FALSE;
+
+ if (cur_node->left != NULL && cur_node->right != NULL) {
+ prev_node = cur_node->left;
+
+ while (prev_node->right != NULL)
+ prev_node = prev_node->right;
+
+ cur_node->key = prev_node->key;
+ cur_node->value = prev_node->value;
+
+ /* Mark node for removal */
+ cur_node = prev_node;
+ }
+
+ child_node = cur_node->left == NULL ? cur_node->right : cur_node->left;
+
+ if (child_node == NULL && pp_tree_rb_is_black ((PTreeRBNode *) cur_node) == TRUE)
+ pp_tree_rb_balance_remove ((PTreeRBNode *) cur_node, root_node);
+
+ /* Replace node with its child */
+ if (cur_node == *root_node) {
+ *root_node = child_node;
+ child_parent = NULL;
+ } else {
+ child_parent = ((PTreeRBNode *) cur_node)->parent;
+
+ if (child_parent->base.left == cur_node)
+ child_parent->base.left = child_node;
+ else
+ child_parent->base.right = child_node;
+ }
+
+ if (child_node != NULL) {
+ ((PTreeRBNode *) child_node)->parent = child_parent;
+
+ /* Check if we need to repaint the node */
+ if (pp_tree_rb_is_black ((PTreeRBNode *) cur_node) == TRUE)
+ ((PTreeRBNode *) child_node)->color = P_TREE_RB_COLOR_BLACK;
+ }
+
+ /* Free unused node */
+ if (key_destroy_func != NULL)
+ key_destroy_func (cur_node->key);
+
+ if (value_destroy_func != NULL)
+ value_destroy_func (cur_node->value);
+
+ p_free (cur_node);
+
+ return TRUE;
+}
+
+void
+p_tree_rb_node_free (PTreeBaseNode *node)
+{
+ p_free (node);
+}
diff --git a/3rdparty/plibsys/src/ptree-rb.h b/3rdparty/plibsys/src/ptree-rb.h
new file mode 100644
index 0000000..7cf20be
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree-rb.h
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTREERB_H
+#define PLIBSYS_HEADER_PTREERB_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+#include "ptree-private.h"
+
+P_BEGIN_DECLS
+
+pboolean p_tree_rb_insert (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value);
+
+pboolean p_tree_rb_remove (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key);
+
+void p_tree_rb_node_free (PTreeBaseNode *node);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTREERB_H */
diff --git a/3rdparty/plibsys/src/ptree.c b/3rdparty/plibsys/src/ptree.c
new file mode 100644
index 0000000..d61aee7
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree.c
@@ -0,0 +1,315 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "ptree.h"
+#include "ptree-avl.h"
+#include "ptree-bst.h"
+#include "ptree-rb.h"
+
+typedef pboolean (*PTreeInsertNode) (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ ppointer key,
+ ppointer value);
+
+typedef pboolean (*PTreeRemoveNode) (PTreeBaseNode **root_node,
+ PCompareDataFunc compare_func,
+ ppointer data,
+ PDestroyFunc key_destroy_func,
+ PDestroyFunc value_destroy_func,
+ pconstpointer key);
+
+typedef void (*PTreeFreeNode) (PTreeBaseNode *node);
+
+struct PTree_ {
+ PTreeBaseNode *root;
+ PTreeInsertNode insert_node_func;
+ PTreeRemoveNode remove_node_func;
+ PTreeFreeNode free_node_func;
+ PDestroyFunc key_destroy_func;
+ PDestroyFunc value_destroy_func;
+ PCompareDataFunc compare_func;
+ ppointer data;
+ PTreeType type;
+ pint nnodes;
+};
+
+P_LIB_API PTree *
+p_tree_new (PTreeType type,
+ PCompareFunc func)
+{
+ return p_tree_new_full (type, (PCompareDataFunc) func, NULL, NULL, NULL);
+}
+
+P_LIB_API PTree *
+p_tree_new_with_data (PTreeType type,
+ PCompareDataFunc func,
+ ppointer data)
+{
+ return p_tree_new_full (type, func, data, NULL, NULL);
+}
+
+P_LIB_API PTree *
+p_tree_new_full (PTreeType type,
+ PCompareDataFunc func,
+ ppointer data,
+ PDestroyFunc key_destroy,
+ PDestroyFunc value_destroy)
+{
+ PTree *ret;
+
+ if (P_UNLIKELY (!(type >= P_TREE_TYPE_BINARY && type <= P_TREE_TYPE_AVL)))
+ return NULL;
+
+ if (P_UNLIKELY (func == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PTree))) == NULL)) {
+ P_ERROR ("PTree::p_tree_new_full: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->type = type;
+ ret->compare_func = func;
+ ret->data = data;
+ ret->key_destroy_func = key_destroy;
+ ret->value_destroy_func = value_destroy;
+
+ switch (type) {
+ case P_TREE_TYPE_BINARY:
+ ret->insert_node_func = p_tree_bst_insert;
+ ret->remove_node_func = p_tree_bst_remove;
+ ret->free_node_func = p_tree_bst_node_free;
+ break;
+ case P_TREE_TYPE_RB:
+ ret->insert_node_func = p_tree_rb_insert;
+ ret->remove_node_func = p_tree_rb_remove;
+ ret->free_node_func = p_tree_rb_node_free;
+ break;
+ case P_TREE_TYPE_AVL:
+ ret->insert_node_func = p_tree_avl_insert;
+ ret->remove_node_func = p_tree_avl_remove;
+ ret->free_node_func = p_tree_avl_node_free;
+ break;
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_tree_insert (PTree *tree,
+ ppointer key,
+ ppointer value)
+{
+ pboolean result;
+
+ if (P_UNLIKELY (tree == NULL))
+ return;
+
+ result = tree->insert_node_func (&tree->root,
+ tree->compare_func,
+ tree->data,
+ tree->key_destroy_func,
+ tree->value_destroy_func,
+ key,
+ value);
+
+ if (result == TRUE)
+ ++tree->nnodes;
+}
+
+P_LIB_API pboolean
+p_tree_remove (PTree *tree,
+ pconstpointer key)
+{
+ pboolean result;
+
+ if (P_UNLIKELY (tree == NULL || tree->root == NULL))
+ return FALSE;
+
+ result = tree->remove_node_func (&tree->root,
+ tree->compare_func,
+ tree->data,
+ tree->key_destroy_func,
+ tree->value_destroy_func,
+ key);
+ if (result == TRUE)
+ --tree->nnodes;
+
+ return result;
+}
+
+P_LIB_API ppointer
+p_tree_lookup (PTree *tree,
+ pconstpointer key)
+{
+ PTreeBaseNode *cur_node;
+ pint cmp_result;
+
+ if (P_UNLIKELY (tree == NULL))
+ return NULL;
+
+ cur_node = tree->root;
+
+ while (cur_node != NULL) {
+ cmp_result = tree->compare_func (key, cur_node->key, tree->data);
+
+ if (cmp_result < 0)
+ cur_node = cur_node->left;
+ else if (cmp_result > 0)
+ cur_node = cur_node->right;
+ else
+ return cur_node->value;
+ }
+
+ return NULL;
+}
+
+P_LIB_API void
+p_tree_foreach (PTree *tree,
+ PTraverseFunc traverse_func,
+ ppointer user_data)
+{
+ PTreeBaseNode *cur_node;
+ PTreeBaseNode *prev_node;
+ pint mod_counter;
+ pboolean need_stop;
+
+ if (P_UNLIKELY (tree == NULL || traverse_func == NULL))
+ return;
+
+ if (P_UNLIKELY (tree->root == NULL))
+ return;
+
+ cur_node = tree->root;
+ mod_counter = 0;
+ need_stop = FALSE;
+
+ while (cur_node != NULL) {
+ if (cur_node->left == NULL) {
+ if (need_stop == FALSE)
+ need_stop = traverse_func (cur_node->key,
+ cur_node->value,
+ user_data);
+
+ cur_node = cur_node->right;
+ } else {
+ prev_node = cur_node->left;
+
+ while (prev_node->right != NULL && prev_node->right != cur_node)
+ prev_node = prev_node->right;
+
+ if (prev_node->right == NULL) {
+ prev_node->right = cur_node;
+ cur_node = cur_node->left;
+
+ ++mod_counter;
+ } else {
+ if (need_stop == FALSE)
+ need_stop = traverse_func (cur_node->key,
+ cur_node->value,
+ user_data);
+
+ cur_node = cur_node->right;
+ prev_node->right = NULL;
+
+ --mod_counter;
+
+ if (need_stop == TRUE && mod_counter == 0)
+ return;
+ }
+ }
+ }
+}
+
+P_LIB_API void
+p_tree_clear (PTree *tree)
+{
+ PTreeBaseNode *cur_node;
+ PTreeBaseNode *prev_node;
+ PTreeBaseNode *next_node;
+
+ if (P_UNLIKELY (tree == NULL || tree->root == NULL))
+ return;
+
+ cur_node = tree->root;
+
+ while (cur_node != NULL) {
+ if (cur_node->left == NULL) {
+ next_node = cur_node->right;
+
+ if (tree->key_destroy_func != NULL)
+ tree->key_destroy_func (cur_node->key);
+
+ if (tree->value_destroy_func != NULL)
+ tree->value_destroy_func (cur_node->value);
+
+ tree->free_node_func (cur_node);
+ --tree->nnodes;
+
+ cur_node = next_node;
+ } else {
+ prev_node = cur_node->left;
+
+ while (prev_node->right != NULL)
+ prev_node = prev_node->right;
+
+ prev_node->right = cur_node;
+ next_node = cur_node->left;
+ cur_node->left = NULL;
+ cur_node = next_node;
+ }
+ }
+
+ tree->root = NULL;
+}
+
+P_LIB_API PTreeType
+p_tree_get_type (const PTree *tree)
+{
+ if (P_UNLIKELY (tree == NULL))
+ return (PTreeType) -1;
+
+ return tree->type;
+}
+
+P_LIB_API pint
+p_tree_get_nnodes (const PTree *tree)
+{
+ if (P_UNLIKELY (tree == NULL))
+ return 0;
+
+ return tree->nnodes;
+}
+
+P_LIB_API void
+p_tree_free (PTree *tree)
+{
+ p_tree_clear (tree);
+ p_free (tree);
+}
diff --git a/3rdparty/plibsys/src/ptree.h b/3rdparty/plibsys/src/ptree.h
new file mode 100644
index 0000000..d43e7ae
--- /dev/null
+++ b/3rdparty/plibsys/src/ptree.h
@@ -0,0 +1,230 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file ptree.h
+ * @brief Binary tree data structure
+ * @author Alexander Saprykin
+ *
+ * #PTree represents a binary search tree structure for faster lookup than
+ * a plain array or a list. It has average O(logN) time complexity to search
+ * a key-value pair, and O(N) in the worst case (when a tree is degenerated into
+ * the list).
+ *
+ * Currently #PTree supports the following tree types:
+ * - unbalanced binary search tree;
+ * - red-black self-balancing tree;
+ * - AVL self-balancing tree.
+ *
+ * Use p_tree_new(), or its detailed variations like p_tree_new_with_data() and
+ * p_tree_new_full() to create a tree structure. Take attention that a caller
+ * owns the key and the value data passed when inserting new nodes, so you
+ * should manually free the memory after the tree usage. Or you can provide
+ * destroy notification functions for the keys and the values separately.
+ *
+ * New key-value pairs can be inserted with p_tree_insert() and removed with
+ * p_tree_remove().
+ *
+ * Use p_tree_lookup() to find the value by a given key. You can also traverse
+ * the tree in-order with p_tree_foreach().
+ *
+ * Release memory with p_tree_free() or clear a tree with p_tree_clear(). Keys
+ * and values would be destroyed only if the corresponding notification
+ * functions were provided.
+ *
+ * Note: all operations with the tree are non-recursive, only iterative calls
+ * are used.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTREE_H
+#define PLIBSYS_HEADER_PTREE_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Tree opaque data structure. */
+typedef struct PTree_ PTree;
+
+/** Internal data organization algorithm for #PTree. */
+typedef enum PTreeType_ {
+ P_TREE_TYPE_BINARY = 0, /**< Unbalanced binary tree. */
+ P_TREE_TYPE_RB = 1, /**< Red-black self-balancing tree. */
+ P_TREE_TYPE_AVL = 2 /**< AVL self-balancing tree. */
+} PTreeType;
+
+/**
+ * @brief Initializes new #PTree.
+ * @param type Tree algorithm type to use, can't be changed later.
+ * @param func Key compare function.
+ * @return Newly initialized #PTree object in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * The caller takes ownership of all the keys and the values passed to the tree.
+ */
+P_LIB_API PTree * p_tree_new (PTreeType type,
+ PCompareFunc func);
+
+/**
+ * @brief Initializes new #PTree with additional data.
+ * @param type Tree algorithm type to use, can't be changed later.
+ * @param func Key compare function.
+ * @param data Data to be passed to @a func along with the keys.
+ * @return Newly initialized #PTree object in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * The caller takes ownership of all the keys and the values passed to the tree.
+ */
+P_LIB_API PTree * p_tree_new_with_data (PTreeType type,
+ PCompareDataFunc func,
+ ppointer data);
+
+/**
+ * @brief Initializes new #PTree with additional data and memory management.
+ * @param type Tree algorithm type to use, can't be changed later.
+ * @param func Key compare function.
+ * @param data Data to be passed to @a func along with the keys.
+ * @param key_destroy Function to call on every key before the node destruction,
+ * maybe NULL.
+ * @param value_destroy Function to call on every value before the node
+ * destruction, maybe NULL.
+ * @return Newly initialized #PTree object in case of success, NULL otherwise.
+ * @since 0.0.1
+ *
+ * Upon every node destruction the corresponding key and value functions would
+ * be called.
+ */
+P_LIB_API PTree * p_tree_new_full (PTreeType type,
+ PCompareDataFunc func,
+ ppointer data,
+ PDestroyFunc key_destroy,
+ PDestroyFunc value_destroy);
+
+/**
+ * @brief Inserts a new key-value pair into a tree.
+ * @param tree #PTree to insert a node in.
+ * @param key Key to insert.
+ * @param value Value corresponding to the given @a key.
+ * @since 0.0.1
+ *
+ * If the @a key already exists in the tree then it will be replaced with the
+ * new one. If a key destroy function was provided it would be called on the old
+ * key. If a value destroy function was provided it would be called on the old
+ * value.
+ */
+P_LIB_API void p_tree_insert (PTree *tree,
+ ppointer key,
+ ppointer value);
+
+/**
+ * @brief Removes a key from a tree.
+ * @param tree #PTree to remove a key from.
+ * @param key A key to lookup.
+ * @return TRUE if the key was removed, FALSE if the key was not found.
+ * @since 0.0.1
+ *
+ * If a key destroy function was provided it would be called on the key. If a
+ * value destroy function was provided it would be called on the old value.
+ */
+P_LIB_API pboolean p_tree_remove (PTree *tree,
+ pconstpointer key);
+
+/**
+ * @brief Lookups a value by a given key.
+ * @param tree #PTree to lookup in.
+ * @param key Key to lookup.
+ * @return Value for the given @a key in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API ppointer p_tree_lookup (PTree *tree,
+ pconstpointer key);
+
+/**
+ * @brief Iterates in-order through the tree nodes.
+ * @param tree A tree to traverse.
+ * @param traverse_func Function for traversing.
+ * @param user_data Additional (maybe NULL) user-provided data for the
+ * @a traverse_func.
+ * @since 0.0.1
+ * @note Morris (non-recursive, non-stack) traversing algorithm is being used.
+ *
+ * The tree should not be modified while traversing. The internal tree structure
+ * can be modified along the traversing process, so keep it in mind for
+ * concurrent access.
+ */
+P_LIB_API void p_tree_foreach (PTree *tree,
+ PTraverseFunc traverse_func,
+ ppointer user_data);
+
+/**
+ * @brief Clears a tree.
+ * @param tree #PTree to clear.
+ * @since 0.0.1
+ * @note Modified Morris (non-recursive, non-stack) traversing algorithm is
+ * being used.
+ *
+ * All the keys will be deleted. Key and value destroy functions would be called
+ * on every node if any of them was provided.
+ */
+P_LIB_API void p_tree_clear (PTree *tree);
+
+/**
+ * @brief Gets a tree algorithm type.
+ * @param tree #PTree object to get the type for.
+ * @return Tree internal organization algorithm used for a given object.
+ * @since 0.0.1
+ */
+P_LIB_API PTreeType p_tree_get_type (const PTree *tree);
+
+/**
+ * @brief Gets node count.
+ * @param tree #PTree to get node count for.
+ * @return Node count.
+ * @since 0.0.1
+ *
+ * If the tree is empty or an invalid pointer is given it returns 0.
+ */
+P_LIB_API pint p_tree_get_nnodes (const PTree *tree);
+
+/**
+ * @brief Frees a previously initialized tree object.
+ * @param tree #PTree object to free.
+ * @since 0.0.1
+ * @note Modified Morris (non-recursive, non-stack) traversing algorithm is
+ * being used.
+ *
+ * All the keys will be deleted. Key and value destroy functions would be called
+ * on every node if any of them was provided.
+ */
+P_LIB_API void p_tree_free (PTree *tree);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTREE_H */
diff --git a/3rdparty/plibsys/src/ptypes.h b/3rdparty/plibsys/src/ptypes.h
new file mode 100644
index 0000000..46f2621
--- /dev/null
+++ b/3rdparty/plibsys/src/ptypes.h
@@ -0,0 +1,1122 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2016 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file ptypes.h
+ * @brief Types definitions
+ * @author Alexander Saprykin
+ *
+ * Every operating system in pair with a compiler has its own set of data types.
+ * Here you can find unified platform independent data types which guarantee the
+ * same bit-size on every supported platform: #pint8, #pint16, #pint32, #pint64
+ * and their unsigned variants. Also other types are defined for convinience:
+ * #ppointer, #pboolean, #pint, #plong, #pdouble and more.
+ *
+ * Along with the types, length and format modifiers are defined. They can be
+ * used to print and scan data from/to a variable.
+ *
+ * Sometimes it is useful to use an integer variable as a pointer, i.e. to
+ * prevent memory allocation when using hash tables or trees. Use special macros
+ * for that case: #PINT_TO_POINTER, #PPOINTER_TO_INT and their variants. Note
+ * that it will not work with 64-bit data types.
+ *
+ * To check data type limits use P_MIN* and P_MAX* macros.
+ *
+ * If you need to check system endianness compare the P_BYTE_ORDER definition
+ * with the #P_LITTLE_ENDIAN or #P_BIG_ENDIAN macro.
+ *
+ * To convert between the little and big endian byte orders use the Px_TO_LE,
+ * Px_TO_BE, Px_FROM_LE and Px_FROM_BE macros. Macros for the network<->host
+ * byte order conversion are also provided: #p_ntohl, #p_ntohs, #p_ntohs and
+ * #p_ntohl. All the described above macros depend on the target system
+ * endianness. Use PUINTx_SWAP_BYTES to manually swap data types independently
+ * from the endianness.
+ *
+ * You can also find some of the function definitions used within the library.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PTYPES_H
+#define PLIBSYS_HEADER_PTYPES_H
+
+#include <plibsysconfig.h>
+#include <pmacros.h>
+
+P_BEGIN_DECLS
+
+/** Type for signed 8 bit. */
+typedef signed char pint8;
+/** Type for unsigned 8 bit. */
+typedef unsigned char puint8;
+/** Type for signed 16 bit. */
+typedef signed short pint16;
+/** Type for unsigned 16 bit. */
+typedef unsigned short puint16;
+/** Type for signed 32 bit. */
+typedef signed int pint32;
+/** Type for unsigned 32 bit. */
+typedef unsigned int puint32;
+
+/**
+ * @var pint64
+ * @brief Type for signed 64 bit.
+ */
+
+/**
+ * @var puint64
+ * @brief Type for unsigned 64 bit.
+ */
+
+#if defined (P_OS_WIN) && (defined (P_CC_MSVC) || defined (P_CC_BORLAND))
+ typedef signed __int64 pint64;
+ typedef unsigned __int64 puint64;
+#else
+# if PLIBSYS_SIZEOF_LONG == 8
+ typedef signed long pint64;
+ typedef unsigned long puint64;
+# else
+ typedef signed long long pint64;
+ typedef unsigned long long puint64;
+# endif
+#endif
+
+/** Type for a pointer. */
+typedef void * ppointer;
+/** Type for a const pointer. */
+typedef const void * pconstpointer;
+
+/** Type for a bool. */
+typedef signed int pboolean;
+/** Type for a char. */
+typedef char pchar;
+/** Type for a short. */
+typedef short pshort;
+/** Type for an int. */
+typedef int pint;
+/** Type for a long. */
+typedef long plong;
+
+/** Type for an unsigned char. */
+typedef unsigned char puchar;
+/** Type for an unsigned short. */
+typedef unsigned short pushort;
+/** Type for an unsigned int. */
+typedef unsigned int puint;
+/** Type for an unsigned long. */
+typedef unsigned long pulong;
+
+/** Type for a float. */
+typedef float pfloat;
+/** Type for a double precision float. */
+typedef double pdouble;
+
+/**
+ * @var pssize
+ * @brief Type for a platform independent signed size_t.
+ */
+
+/**
+ * @var psize
+ * @brief Type for a platform independent size_t.
+ */
+
+/**
+ * @def PSIZE_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #psize or #pssize type for printing and scanning values. It is a string
+ * literal, but doesn't include the percent sign so you can add precision and
+ * length modifiers and append a conversion specifier.
+ * @code
+ * psize size_val = 256;
+ * printf ("%#" PSIZE_MODIFIER "x", size_val);
+ * @endcode
+ */
+
+/**
+ * @def PSSIZE_FORMAT
+ * @brief Platform dependent conversion specifier of #pssize type for printing
+ * and scanning values.
+ * @code
+ * pssize size_val = 100;
+ * printf ("%" PSSIZE_FORMAT, size_val);
+ * @endcode
+ */
+
+/**
+ * @def PSIZE_FORMAT
+ * @brief Platform dependent conversion specifier of #psize type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def P_MAXSIZE
+ * @brief Maximum value of a #psize type.
+ */
+
+/**
+ * @def P_MINSSIZE
+ * @brief Minimum value of a #pssize type.
+ */
+
+/**
+ * @def P_MAXSSIZE
+ * @brief Maximum value of a #pssize type.
+ */
+
+#if PLIBSYS_SIZEOF_SIZE_T == 8
+# if defined (P_OS_WIN) && (defined (P_CC_MSVC) || defined (P_CC_BORLAND))
+ typedef signed __int64 pssize;
+ typedef unsigned __int64 psize;
+ #define PSIZE_MODIFIER "I64"
+ #define PSSIZE_FORMAT "I64d"
+ #define PSIZE_FORMAT "I64u"
+ #define P_MAXSIZE P_MAXUINT64
+ #define P_MINSSIZE P_MININT64
+ #define P_MAXSSIZE P_MAXINT64
+# else
+# if PLIBSYS_SIZEOF_LONG == 8
+ typedef long pssize;
+ typedef unsigned long psize;
+ #define PSIZE_MODIFIER "l"
+ #define PSSIZE_FORMAT "li"
+ #define PSIZE_FORMAT "lu"
+ #define P_MAXSIZE P_MAXULONG
+ #define P_MINSSIZE P_MINLONG
+ #define P_MAXSSIZE P_MAXLONG
+# else
+ typedef long long pssize;
+ typedef unsigned long long psize;
+ #define PSIZE_MODIFIER "ll"
+ #define PSSIZE_FORMAT "lli"
+ #define PSIZE_FORMAT "llu"
+ #define P_MAXSIZE P_MAXUINT64
+ #define P_MINSSIZE P_MININT64
+ #define P_MAXSSIZE P_MAXINT64
+# endif
+# endif
+#else
+ typedef signed int pssize;
+ typedef unsigned int psize;
+ #define PSIZE_MODIFIER ""
+ #define PSSIZE_FORMAT "i"
+ #define PSIZE_FORMAT "u"
+ #define P_MAXSIZE P_MAXUINT
+ #define P_MINSSIZE P_MININT
+ #define P_MAXSSIZE P_MAXINT
+#endif
+
+/**
+ * @var pintptr
+ * @brief Type for a platform independent signed pointer represented by an
+ * integer.
+ */
+
+/**
+ * @var puintptr
+ * @brief Type for a platform independent unsigned pointer represented by an
+ * integer.
+ */
+
+/**
+ * @def PINTPTR_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #pintptr or #puintptr type for printing and scanning values. It is a string
+ * literal, but doesn't include the percent sign so you can add precision and
+ * length modifiers and append a conversion specifier.
+ */
+
+/**
+ * @def PINTPTR_FORMAT
+ * @brief Platform dependent conversion specifier of #pintptr type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PUINTPTR_FORMAT
+ * @brief Platform dependent conversion specifier of #puintptr type for
+ * printing and scanning values.
+ */
+
+#if PLIBSYS_SIZEOF_VOID_P == 8
+# if defined (P_OS_WIN) && (defined (P_CC_MSVC) || defined (P_CC_BORLAND))
+ typedef signed __int64 pintptr;
+ typedef unsigned __int64 puintptr;
+ #define PINTPTR_MODIFIER "I64"
+ #define PINTPTR_FORMAT "I64i"
+ #define PUINTPTR_FORMAT "I64u"
+# else
+# if PLIBSYS_SIZEOF_LONG == 8
+ typedef long pintptr;
+ typedef unsigned long puintptr;
+ #define PINTPTR_MODIFIER "l"
+ #define PINTPTR_FORMAT "li"
+ #define PUINTPTR_FORMAT "lu"
+# else
+ typedef long long pintptr;
+ typedef unsigned long long puintptr;
+ #define PINTPTR_MODIFIER "ll"
+ #define PINTPTR_FORMAT "lli"
+ #define PUINTPTR_FORMAT "llu"
+# endif
+# endif
+#else
+ typedef signed int pintptr;
+ typedef unsigned int puintptr;
+ #define PINTPTR_MODIFIER ""
+ #define PINTPTR_FORMAT "i"
+ #define PUINTPTR_FORMAT "u"
+#endif
+
+/** Platform independent offset_t definition. */
+typedef pint64 poffset;
+
+#if PLIBSYS_SIZEOF_VOID_P == 8
+# define P_INT_TO_POINTER(i) ((void *) (long long) (i))
+# define P_POINTER_TO_INT(p) ((int) (long long) (p))
+# define PPOINTER_TO_INT(p) ((pint) ((pint64) (p)))
+# define PPOINTER_TO_UINT(p) ((puint) ((puint64) (p)))
+# define PINT_TO_POINTER(i) ((ppointer) (pint64) (i))
+# define PUINT_TO_POINTER(u) ((ppointer) (puint64) (u))
+#else
+# define P_INT_TO_POINTER(i) ((void *) (long) (i))
+# define P_POINTER_TO_INT(p) ((int) (long) (p))
+# define PPOINTER_TO_INT(p) ((pint) ((plong) (p)))
+# define PPOINTER_TO_UINT(p) ((puint) ((pulong) (p)))
+# define PINT_TO_POINTER(i) ((ppointer) (plong) (i))
+# define PUINT_TO_POINTER(u) ((ppointer) (pulong) (u))
+#endif
+
+/**
+ * @def P_INT_TO_POINTER
+ * @brief Casts an int to a pointer.
+ * @param i Variable to cast.
+ * @return Casted variable.
+ * @since 0.0.1
+ */
+
+/**
+ * @def P_POINTER_TO_INT
+ * @brief Casts a pointer to an int.
+ * @param p Pointer to cast.
+ * @return Casted pointer.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PPOINTER_TO_INT
+ * @brief Casts a #ppointer to a #pint value.
+ * @param p #ppointer to cast.
+ * @return Casted #ppointer.
+ * @since 0.0.1
+ */
+
+ /**
+ * @def PPOINTER_TO_UINT
+ * @brief Casts a #ppointer to a #pint value.
+ * @param p #ppointer to cast.
+ * @return Casted #ppointer.
+ * @since 0.0.1
+ */
+
+ /**
+ * @def PINT_TO_POINTER
+ * @brief Casts a #pint value to a #ppointer.
+ * @param i #pint to cast.
+ * @return Casted #pint.
+ * @since 0.0.1
+ */
+
+ /**
+ * @def PUINT_TO_POINTER
+ * @brief Casts a #puint value to a #ppointer.
+ * @param u #puint to cast.
+ * @return Casted #puint.
+ * @since 0.0.1
+ */
+
+/** Casts a #psize value to a #ppointer. */
+#define PSIZE_TO_POINTER(i) ((ppointer) ((psize) (i)))
+/** Casts a #ppointer to a #psize value. */
+#define PPOINTER_TO_PSIZE(p) ((psize) (p))
+
+/** Min value for a 8-bit int. */
+#define P_MININT8 ((pint8) 0x80)
+/** Max value for a 8-bit int. */
+#define P_MAXINT8 ((pint8) 0x7F)
+/** Max value for a 8-bit unsigned int. */
+#define P_MAXUINT8 ((puint8) 0xFF)
+
+/** Min value for a 16-bit int. */
+#define P_MININT16 ((pint16) 0x8000)
+/** Max value for a 16-bit int. */
+#define P_MAXINT16 ((pint16) 0x7FFF)
+/** Max value for a 16-bit unsigned int. */
+#define P_MAXUINT16 ((puint16) 0xFFFF)
+
+/** Min value for a 32-bit int. */
+#define P_MININT32 ((pint32) 0x80000000)
+/** Max value for a 32-bit int. */
+#define P_MAXINT32 ((pint32) 0x7FFFFFFF)
+/** Max value for a 32-bit unsigned int. */
+#define P_MAXUINT32 ((puint32) 0xFFFFFFFF)
+
+/** Min value for a 64-bit int. */
+#define P_MININT64 ((pint64) 0x8000000000000000LL)
+/** Max value for a 64-bit int. */
+#define P_MAXINT64 ((pint64) 0x7FFFFFFFFFFFFFFFLL)
+/** Max value for a 64-bit unsigned int. */
+#define P_MAXUINT64 ((puint64) 0xFFFFFFFFFFFFFFFFULL)
+
+/**
+ * @def PINT16_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #pint16 or #puint16 type for printing and scanning values. It is a string
+ * literal, but doesn't include the percent sign so you can add precision and
+ * length modifiers and append a conversion specifier.
+ */
+
+/**
+ * @def PINT16_FORMAT
+ * @brief Platform dependent conversion specifier of #pint16 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PUINT16_FORMAT
+ * @brief Platform dependent conversion specifier of #puint16 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PINT32_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #pint32 or #puint32 type for printing and scanning values. It is a string
+ * literal, but doesn't include the percent sign so you can add precision and
+ * length modifiers and append a conversion specifier.
+ */
+
+/**
+ * @def PINT32_FORMAT
+ * @brief Platform dependent conversion specifier of #pint32 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PUINT32_FORMAT
+ * @brief Platform dependent conversion specifier of #puint32 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PINT64_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #pint64 or #puint64 type for printing and scanning values. It is a string
+ * literal, but doesn't include the percent sign so you can add precision and
+ * length modifiers and append a conversion specifier.
+ */
+
+/**
+ * @def PINT64_FORMAT
+ * @brief Platform dependent conversion specifier of #pint64 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def PUINT64_FORMAT
+ * @brief Platform dependent conversion specifier of #puint64 type for printing
+ * and scanning values.
+ */
+
+/**
+ * @def POFFSET_MODIFIER
+ * @brief Platform dependent length modifier for conversion specifiers of
+ * #poffset type for printing and scanning values. It is a string literal, but
+ * doesn't include the percent sign so you can add precision and length
+ * modifiers and append a conversion specifier.
+ */
+
+/**
+ * @def POFFSET_FORMAT
+ * @brief Platform dependent conversion specifier of #poffset type for printing
+ * and scanning values.
+ */
+
+#if defined (P_OS_WIN) && (defined (P_CC_MSVC) || defined (P_CC_BORLAND))
+ #define PINT16_MODIFIER "h"
+#else
+ #define PINT16_MODIFIER ""
+#endif
+
+#define PINT16_FORMAT "hi"
+#define PUINT16_FORMAT "hu"
+
+#define PINT32_MODIFIER ""
+#define PINT32_FORMAT "i"
+#define PUINT32_FORMAT "u"
+
+#if defined (P_OS_WIN) && (defined (P_CC_MSVC) || defined (P_CC_BORLAND))
+ #define PINT64_MODIFIER "I64"
+ #define PINT64_FORMAT "I64i"
+ #define PUINT64_FORMAT "I64u"
+#else
+# if PLIBSYS_SIZEOF_LONG == 8
+ #define PINT64_MODIFIER "l"
+ #define PINT64_FORMAT "li"
+ #define PUINT64_FORMAT "lu"
+# else
+ #define PINT64_MODIFIER "ll"
+ #define PINT64_FORMAT "lli"
+ #define PUINT64_FORMAT "llu"
+# endif
+#endif
+
+#define POFFSET_MODIFIER PINT64_MODIFIER
+#define POFFSET_FORMAT PINT64_FORMAT
+
+/* Endian checks, see P_BYTE_ORDER in plibsysconfig.h */
+
+/** Little endian mark. */
+#define P_LITTLE_ENDIAN 1234
+/** Big endian mark. */
+#define P_BIG_ENDIAN 4321
+
+/**
+ * @def PINT16_TO_LE
+ * @brief Swaps a #pint16 variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT16_TO_LE
+ * @brief Swaps a #puint16 variable from the host to the little the endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT16_TO_BE
+ * @brief Swaps a #pint16 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT16_TO_BE
+ * @brief Swaps a #puint16 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT32_TO_LE
+ * @brief Swaps a #pint32 variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT32_TO_LE
+ * @brief Swaps a #puint32 variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT32_TO_BE
+ * @brief Swaps a #pint32 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT32_TO_BE
+ * @brief Swaps a #puint32 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT64_TO_LE
+ * @brief Swaps a #pint64 variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT64_TO_LE
+ * @brief Swaps a #puint64 variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT64_TO_BE
+ * @brief Swaps a #pint64 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT64_TO_BE
+ * @brief Swaps a #puint64 variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PLONG_TO_LE
+ * @brief Swaps a #plong variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PULONG_TO_LE
+ * @brief Swaps a #pulong variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PLONG_TO_BE
+ * @brief Swaps a #plong variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PULONG_TO_BE
+ * @brief Swaps a #pulong variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PSSIZE_TO_LE
+ * @brief Swaps a #pssize variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PSIZE_TO_LE
+ * @brief Swaps a #psize variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PSSIZE_TO_BE
+ * @brief Swaps a #pssize variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PSIZE_TO_BE
+ * @brief Swaps a #psize variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT_TO_LE
+ * @brief Swaps a #pint variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT_TO_LE
+ * @brief Swaps a #puint variable from the host to the little endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PINT_TO_BE
+ * @brief Swaps a #pint variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+/**
+ * @def PUINT_TO_BE
+ * @brief Swaps a #puint variable from the host to the big endian order.
+ * @param val Value to swap.
+ * @return Swapped value.
+ * @since 0.0.1
+ */
+
+#if P_BYTE_ORDER == P_LITTLE_ENDIAN
+ #define PINT16_TO_LE(val) ((pint16) (val))
+ #define PUINT16_TO_LE(val) ((puint16) (val))
+ #define PINT16_TO_BE(val) ((pint16) PUINT16_SWAP_BYTES (val))
+ #define PUINT16_TO_BE(val) (PUINT16_SWAP_BYTES (val))
+ #define PINT32_TO_LE(val) ((pint32) (val))
+ #define PUINT32_TO_LE(val) ((puint32) (val))
+ #define PINT32_TO_BE(val) ((pint32) PUINT32_SWAP_BYTES (val))
+ #define PUINT32_TO_BE(val) (PUINT32_SWAP_BYTES (val))
+ #define PINT64_TO_LE(val) ((pint64) (val))
+ #define PUINT64_TO_LE(val) ((puint64) (val))
+ #define PINT64_TO_BE(val) ((pint64) PUINT64_SWAP_BYTES (val))
+ #define PUINT64_TO_BE(val) (PUINT64_SWAP_BYTES (val))
+# if PLIBSYS_SIZEOF_LONG == 8
+ #define PLONG_TO_LE(val) ((plong) PINT64_TO_LE (val))
+ #define PULONG_TO_LE(val) ((pulong) PUINT64_TO_LE (val))
+ #define PLONG_TO_BE(val) ((plong) PINT64_TO_BE (val))
+ #define PULONG_TO_BE(val) ((pulong) PUINT64_TO_BE (val))
+# else
+ #define PLONG_TO_LE(val) ((plong) PINT32_TO_LE (val))
+ #define PULONG_TO_LE(val) ((pulong) PUINT32_TO_LE (val))
+ #define PLONG_TO_BE(val) ((plong) PINT32_TO_BE (val))
+ #define PULONG_TO_BE(val) ((pulong) PUINT32_TO_BE (val))
+# endif
+# if PLIBSYS_SIZEOF_SIZE_T == 8
+ #define PSIZE_TO_LE(val) ((psize) PUINT64_TO_LE (val))
+ #define PSSIZE_TO_LE(val) ((pssize) PINT64_TO_LE (val))
+ #define PSIZE_TO_BE(val) ((psize) PUINT64_TO_BE (val))
+ #define PSSIZE_TO_BE(val) ((pssize) PINT64_TO_BE (val))
+# else
+ #define PSIZE_TO_LE(val) ((psize) PUINT32_TO_LE (val))
+ #define PSSIZE_TO_LE(val) ((pssize) PINT32_TO_LE (val))
+ #define PSIZE_TO_BE(val) ((psize) PUINT32_TO_BE (val))
+ #define PSSIZE_TO_BE(val) ((pssize) PINT32_TO_BE (val))
+# endif
+ #define PINT_TO_LE(val) ((pint) PINT32_TO_LE (val))
+ #define PUINT_TO_LE(val) ((puint) PUINT32_TO_LE (val))
+ #define PINT_TO_BE(val) ((pint) PINT32_TO_BE (val))
+ #define PUINT_TO_BE(val) ((puint) PUINT32_TO_BE (val))
+
+#else
+ #define PINT16_TO_LE(val) ((pint16) PUINT16_SWAP_BYTES (val))
+ #define PUINT16_TO_LE(val) (PUINT16_SWAP_BYTES (val))
+ #define PINT16_TO_BE(val) ((pint16) (val))
+ #define PUINT16_TO_BE(val) ((puint16) (val))
+ #define PINT32_TO_LE(val) ((pint32) PUINT32_SWAP_BYTES (val))
+ #define PUINT32_TO_LE(val) (PUINT32_SWAP_BYTES (val))
+ #define PINT32_TO_BE(val) ((pint32) (val))
+ #define PUINT32_TO_BE(val) ((puint32) (val))
+ #define PINT64_TO_LE(val) ((pint64) PUINT64_SWAP_BYTES (val))
+ #define PUINT64_TO_LE(val) (PUINT64_SWAP_BYTES (val))
+ #define PINT64_TO_BE(val) ((pint64) (val))
+ #define PUINT64_TO_BE(val) ((puint64) (val))
+# if PLIBSYS_SIZEOF_LONG == 8
+ #define PLONG_TO_LE(val) ((plong) PINT64_TO_LE (val))
+ #define PULONG_TO_LE(val) ((pulong) PUINT64_TO_LE (val))
+ #define PLONG_TO_BE(val) ((plong) PINT64_TO_BE (val))
+ #define PULONG_TO_BE(val) ((pulong) PUINT64_TO_BE (val))
+# else
+ #define PLONG_TO_LE(val) ((plong) PINT32_TO_LE (val))
+ #define PULONG_TO_LE(val) ((pulong) PUINT32_TO_LE (val))
+ #define PLONG_TO_BE(val) ((plong) PINT32_TO_BE (val))
+ #define PULONG_TO_BE(val) ((pulong) PUINT32_TO_BE (val))
+# endif
+# if PLIBSYS_SIZEOF_SIZE_T == 8
+ #define PSIZE_TO_LE(val) ((psize) PUINT64_TO_LE (val))
+ #define PSSIZE_TO_LE(val) ((pssize) PINT64_TO_LE (val))
+ #define PSIZE_TO_BE(val) ((psize) PUINT64_TO_BE (val))
+ #define PSSIZE_TO_BE(val) ((pssize) PINT64_TO_BE (val))
+# else
+ #define PSIZE_TO_LE(val) ((psize) PUINT32_TO_LE (val))
+ #define PSSIZE_TO_LE(val) ((pssize) PINT32_TO_LE (val))
+ #define PSIZE_TO_BE(val) ((psize) PUINT32_TO_BE (val))
+ #define PSSIZE_TO_BE(val) ((pssize) PINT32_TO_BE (val))
+# endif
+ #define PINT_TO_LE(val) ((pint) PINT32_TO_LE (val))
+ #define PUINT_TO_LE(val) ((puint) PUINT32_TO_LE (val))
+ #define PINT_TO_BE(val) ((pint) PINT32_TO_BE (val))
+ #define PUINT_TO_BE(val) ((puint) PUINT32_TO_BE (val))
+#endif
+
+/* Functions for bit swapping */
+
+/**
+ * @brief Swaps a 16-bit unsigned int.
+ * @param val Value to swap.
+ * @return Swapped 16-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT16_SWAP_BYTES(val) \
+ ((puint16) (((puint16) (val)) >> 8 | ((puint16) (val)) << 8))
+
+/**
+ * @brief Swaps a 32-bit unsigned int.
+ * @param val Value to swap.
+ * @return Swapped 32-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT32_SWAP_BYTES(val) ((puint32) ( \
+ (((puint32) (val)) >> 24) | \
+ ((((puint32) (val)) << 8) & ((puint32) 0x00FF0000U)) | \
+ ((((puint32) (val)) >> 8) & ((puint32) 0x0000FF00U)) | \
+ (((puint32) (val)) << 24)))
+
+/**
+ * @brief Swaps a 64-bit unsigned int.
+ * @param val Value to swap.
+ * @return Swapped 64-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT64_SWAP_BYTES(val) ((puint64) ( \
+ (((puint64) (val)) >> 56) | \
+ ((((puint64) (val)) << 40) & ((puint64) 0x00FF000000000000ULL)) | \
+ ((((puint64) (val)) << 24) & ((puint64) 0x0000FF0000000000ULL)) | \
+ ((((puint64) (val)) << 8) & ((puint64) 0x000000FF00000000ULL)) | \
+ ((((puint64) (val)) >> 8) & ((puint64) 0x00000000FF000000ULL)) | \
+ ((((puint64) (val)) >> 24) & ((puint64) 0x0000000000FF0000ULL)) | \
+ ((((puint64) (val)) >> 40) & ((puint64) 0x000000000000FF00ULL)) | \
+ (((puint64) (val)) << 56)))
+
+/* Functions, similar to ?_TO_? functions */
+
+/**
+ * @brief Swaps a 16-bit int from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 16-bit int.
+ * @since 0.0.1
+ */
+#define PINT16_FROM_LE(val) (PINT16_TO_LE (val))
+
+/**
+ * @brief Swaps a 16-bit unsigned int from the little endian byte order to the
+ * host one.
+ * @param val Value to swap.
+ * @return Swapped 16-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT16_FROM_LE(val) (PUINT16_TO_LE (val))
+
+/**
+ * @brief Swaps a 16-bit int from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 16-bit int.
+ * @since 0.0.1
+ */
+#define PINT16_FROM_BE(val) (PINT16_TO_BE (val))
+
+/**
+ * @brief Swaps a 16-bit unsigned int from the big endian byte order to the host
+ * one.
+ * @param val Value to swap.
+ * @return Swapped 16-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT16_FROM_BE(val) (PUINT16_TO_BE (val))
+
+
+/**
+ * @brief Swaps a 32-bit int from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 32-bit int.
+ * @since 0.0.1
+ */
+#define PINT32_FROM_LE(val) (PINT32_TO_LE (val))
+
+/**
+ * @brief Swaps a 32-bit unsigned int from the little endian byte order to the
+ * host one.
+ * @param val Value to swap.
+ * @return Swapped 32-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT32_FROM_LE(val) (PUINT32_TO_LE (val))
+
+/**
+ * @brief Swaps a 32-bit int from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 32-bit int.
+ * @since 0.0.1
+ */
+#define PINT32_FROM_BE(val) (PINT32_TO_BE (val))
+
+/**
+ * @brief Swaps a 32-bit unsigned int from the big endian byte order to the host
+ * one.
+ * @param val Value to swap.
+ * @return Swapped 32-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT32_FROM_BE(val) (PUINT32_TO_BE (val))
+
+/**
+ * @brief Swaps a 64-bit int from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 64-bit int.
+ * @since 0.0.1
+ */
+#define PINT64_FROM_LE(val) (PINT64_TO_LE (val))
+
+/**
+ * @brief Swaps a 64-bit unsigned int from the little endian byte order to the
+ * host one.
+ * @param val Value to swap.
+ * @return Swapped 64-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT64_FROM_LE(val) (PUINT64_TO_LE (val))
+
+/**
+ * @brief Swaps a 64-bit int from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped 64-bit int.
+ * @since 0.0.1
+ */
+#define PINT64_FROM_BE(val) (PINT64_TO_BE (val))
+
+/**
+ * @brief Swaps a 64-bit unsigned int from the big endian byte order to the host
+ * one.
+ * @param val Value to swap.
+ * @return Swapped 64-bit unsigned int.
+ * @since 0.0.1
+ */
+#define PUINT64_FROM_BE(val) (PUINT64_TO_BE (val))
+
+/**
+ * @brief Swaps a long int from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped long int.
+ * @since 0.0.1
+ */
+#define PLONG_FROM_LE(val) (PLONG_TO_LE (val))
+
+/**
+ * @brief Swaps an unsigned long int from the little endian byte order to the
+ * host one.
+ * @param val Value to swap.
+ * @return Swapped unsigned long int.
+ * @since 0.0.1
+ */
+#define PULONG_FROM_LE(val) (PULONG_TO_LE (val))
+
+/**
+ * @brief Swaps a long int from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped long int.
+ * @since 0.0.1
+ */
+#define PLONG_FROM_BE(val) (PLONG_TO_BE (val))
+
+/**
+ * @brief Swaps an unsigned long int from the big endian byte order to the host
+ * one.
+ * @param val Value to swap.
+ * @return Swapped unsigned long int.
+ * @since 0.0.1
+ */
+#define PULONG_FROM_BE(val) (PULONG_TO_BE (val))
+
+/**
+ * @brief Swaps a #pint from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #pint.
+ * @since 0.0.1
+ */
+#define PINT_FROM_LE(val) (PINT_TO_LE (val))
+
+/**
+ * @brief Swaps a #puint from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #puint.
+ * @since 0.0.1
+ */
+#define PUINT_FROM_LE(val) (PUINT_TO_LE (val))
+
+/**
+ * @brief Swaps a #pint from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #pint.
+ * @since 0.0.1
+ */
+#define PINT_FROM_BE(val) (PINT_TO_BE (val))
+
+/**
+ * @brief Swaps a #puint from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #puint.
+ * @since 0.0.1
+ */
+#define PUINT_FROM_BE(val) (PUINT_TO_BE (val))
+
+/**
+ * @brief Swaps a #psize from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #psize.
+ * @since 0.0.1
+ */
+#define PSIZE_FROM_LE(val) (PSIZE_TO_LE (val))
+
+/**
+ * @brief Swaps a #pssize from the little endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #pssize.
+ * @since 0.0.1
+ */
+#define PSSIZE_FROM_LE(val) (PSSIZE_TO_LE (val))
+
+/**
+ * @brief Swaps a #psize from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #psize.
+ * @since 0.0.1
+ */
+#define PSIZE_FROM_BE(val) (PSIZE_TO_BE (val))
+
+/**
+ * @brief Swaps a #pssize from the big endian byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped #pssize.
+ * @since 0.0.1
+ */
+#define PSSIZE_FROM_BE(val) (PSSIZE_TO_BE (val))
+
+/* Host-network order functions */
+
+/**
+ * @brief Swaps a long int from the network byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped long int.
+ * @since 0.0.1
+ */
+#define p_ntohl(val) (PUINT32_FROM_BE (val))
+
+/**
+ * @brief Swaps a short int from the network byte order to the host one.
+ * @param val Value to swap.
+ * @return Swapped short int.
+ * @since 0.0.1
+ */
+#define p_ntohs(val) (PUINT16_FROM_BE (val))
+
+/**
+ * @brief Swaps a long int from the host byte order to the network one.
+ * @param val Value to swap.
+ * @return Swapped long int.
+ * @since 0.0.1
+ */
+#define p_htonl(val) (PUINT32_TO_BE (val))
+
+/**
+ * @brief Swaps a short int from the host byte order to the network one.
+ * @param val Value to swap.
+ * @return Swapped short int.
+ * @since 0.0.1
+ */
+#define p_htons(val) (PUINT16_TO_BE (val))
+
+#ifndef FALSE
+/** Type definition for a false boolean value. */
+# define FALSE (0)
+#endif
+
+#ifndef TRUE
+/** Type definition for a true boolean value. */
+# define TRUE (!FALSE)
+#endif
+
+/**
+ * @brief Platform independent system handle.
+ */
+typedef void * P_HANDLE;
+
+/**
+ * @brief Function to traverse through a key-value container.
+ * @param key The key of an item.
+ * @param value The value of the item.
+ * @param user_data Data provided by a user, maybe NULL.
+ * @return FALSE to continue traversing, TRUE to stop it.
+ * @since 0.0.1
+ */
+typedef pboolean (*PTraverseFunc) (ppointer key,
+ ppointer value,
+ ppointer user_data);
+
+/**
+ * @brief General purpose function.
+ * @param data Main argument related to a context value.
+ * @param user_data Additional (maybe NULL) user-provided data.
+ * @since 0.0.1
+ */
+typedef void (*PFunc) (ppointer data, ppointer user_data);
+
+/**
+ * @brief Object destroy notification function.
+ * @param data Pointer to an object to be destroyed.
+ * @since 0.0.1
+ */
+typedef void (*PDestroyFunc) (ppointer data);
+
+/**
+ * @brief Compares two values.
+ * @param a First value to compare.
+ * @param b Second value to compare.
+ * @return -1 if the first value is less than the second, 1 if the first value
+ * is greater than the second, 0 otherwise.
+ * @since 0.0.1
+ */
+typedef pint (*PCompareFunc) (pconstpointer a, pconstpointer b);
+
+/**
+ * @brief Compares two values with additional data.
+ * @param a First value to compare.
+ * @param b Second value to compare.
+ * @param data Addition data, may be NULL.
+ * @return -1 if the first value is less than the second, 1 if the first value
+ * is greater than the second, 0 otherwise.
+ * @since 0.0.1
+ */
+typedef pint (*PCompareDataFunc) (pconstpointer a, pconstpointer b, ppointer data);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PTYPES_H */
diff --git a/3rdparty/plibsys/src/puthread-amiga.c b/3rdparty/plibsys/src/puthread-amiga.c
new file mode 100644
index 0000000..ac23496
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-amiga.c
@@ -0,0 +1,673 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "pcondvariable.h"
+#include "plist.h"
+#include "pmutex.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <proto/exec.h>
+#include <proto/dos.h>
+
+#define PUTHREAD_AMIGA_MAX_TLS_KEYS 128
+#define PUTHREAD_AMIGA_MIN_STACK 524288
+#define PUTHREAD_AMIGA_MAX_CLEANS 4
+
+typedef struct {
+ pboolean in_use;
+ PDestroyFunc free_func;
+} PUThreadTLSKey;
+
+typedef struct {
+ pint id;
+ struct Task *task;
+ jmp_buf jmpbuf;
+ ppointer tls_values[PUTHREAD_AMIGA_MAX_TLS_KEYS];
+} PUThreadInfo;
+
+struct PUThread_ {
+ PUThreadBase base;
+ PUThreadFunc proxy;
+ PCondVariable *join_cond;
+ struct Task *task;
+};
+
+typedef pint puthread_key_t;
+
+struct PUThreadKey_ {
+ puthread_key_t key;
+ PDestroyFunc free_func;
+};
+
+static PMutex *pp_uthread_glob_mutex = NULL;
+static PList *pp_uthread_list = NULL;
+static pint pp_uthread_last_id = 0;
+
+static PUThreadTLSKey pp_uthread_tls_keys[PUTHREAD_AMIGA_MAX_TLS_KEYS];
+
+static pint pp_uthread_get_amiga_priority (PUThreadPriority prio);
+static puthread_key_t pp_uthread_get_tls_key (PUThreadKey *key);
+static pint pp_uthread_find_next_id (void);
+static PUThreadInfo * pp_uthread_find_thread_info (struct Task *task);
+static PUThreadInfo * pp_uthread_find_or_create_thread_info (struct Task *task);
+static pint pp_uthread_amiga_proxy (void);
+
+static pint
+pp_uthread_get_amiga_priority (PUThreadPriority prio)
+{
+ /* Priority limit is [-128, 127] */
+
+ switch (prio) {
+ case P_UTHREAD_PRIORITY_INHERIT:
+ return 0;
+ case P_UTHREAD_PRIORITY_IDLE:
+ return -128;
+ case P_UTHREAD_PRIORITY_LOWEST:
+ return -50;
+ case P_UTHREAD_PRIORITY_LOW:
+ return -25;
+ case P_UTHREAD_PRIORITY_NORMAL:
+ return 0;
+ case P_UTHREAD_PRIORITY_HIGH:
+ return 25;
+ case P_UTHREAD_PRIORITY_HIGHEST:
+ return 50;
+ case P_UTHREAD_PRIORITY_TIMECRITICAL:
+ return 127;
+ default:
+ return 0;
+ }
+}
+
+static puthread_key_t
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ puthread_key_t thread_key;
+ pint key_idx;
+
+ thread_key = (puthread_key_t) p_atomic_int_get (&key->key);
+
+ if (P_LIKELY (thread_key >= 0))
+ return thread_key;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ if (key->key >= 0) {
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ return key->key;
+ }
+
+ /* Find free TLS key index */
+
+ for (key_idx = 0; key_idx < PUTHREAD_AMIGA_MAX_TLS_KEYS; ++key_idx) {
+ if (P_LIKELY (pp_uthread_tls_keys[key_idx].in_use == FALSE)) {
+ pp_uthread_tls_keys[key_idx].in_use = TRUE;
+ pp_uthread_tls_keys[key_idx].free_func = key->free_func;
+
+ break;
+ }
+ }
+
+ if (key_idx == PUTHREAD_AMIGA_MAX_TLS_KEYS) {
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: all slots for TLS keys are used");
+ return -1;
+ }
+
+ key->key = key_idx;
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ return key_idx;
+}
+
+/* Must be used only inside a protected critical region */
+
+static pint
+pp_uthread_find_next_id (void)
+{
+ PList *cur_list;
+ PUThreadInfo *thread_info;
+ pboolean have_dup;
+ pboolean was_found = FALSE;
+ pint cur_id = pp_uthread_last_id;
+ pint of_counter = 0;
+
+ while (was_found == FALSE && of_counter < 2) {
+ have_dup = FALSE;
+ cur_id = (cur_id == P_MAXINT32) ? 0 : cur_id + 1;
+
+ if (cur_id == 0)
+ ++of_counter;
+
+ for (cur_list = pp_uthread_list; cur_list != NULL; cur_list = cur_list->next) {
+ thread_info = (PUThreadInfo *) cur_list->data;
+
+ if (thread_info->id == cur_id) {
+ have_dup = TRUE;
+ break;
+ }
+ }
+
+ if (have_dup == FALSE)
+ was_found = TRUE;
+ }
+
+ if (P_UNLIKELY (of_counter == 2))
+ return -1;
+
+ pp_uthread_last_id = cur_id;
+
+ return cur_id;
+}
+
+/* Must be used only inside a protected critical region */
+
+static PUThreadInfo *
+pp_uthread_find_thread_info (struct Task *task)
+{
+ PList *cur_list;
+ PUThreadInfo *thread_info;
+
+ for (cur_list = pp_uthread_list; cur_list != NULL; cur_list = cur_list->next) {
+ thread_info = (PUThreadInfo *) cur_list->data;
+
+ if (thread_info->task == task)
+ return thread_info;
+ }
+
+ return NULL;
+}
+
+/* Must be used only inside a protected critical region */
+
+static PUThreadInfo *
+pp_uthread_find_or_create_thread_info (struct Task *task)
+{
+ PUThreadInfo *thread_info;
+ pint task_id;
+
+ thread_info = pp_uthread_find_thread_info (task);
+
+ if (thread_info == NULL) {
+ /* Call is from a forein thread */
+
+ task_id = pp_uthread_find_next_id ();
+
+ if (P_UNLIKELY (task_id == -1)) {
+ /* Beyond the limit of the number of threads */
+ P_ERROR ("PUThread::pp_uthread_find_or_create_thread_info: no free thread slots left");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((thread_info = p_malloc0 (sizeof (PUThreadInfo))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_find_or_create_thread_info: failed to allocate memory");
+ return NULL;
+ }
+
+ thread_info->id = task_id;
+ thread_info->task = task;
+
+ pp_uthread_list = p_list_append (pp_uthread_list, thread_info);
+ }
+
+ return thread_info;
+}
+
+static pint
+pp_uthread_amiga_proxy (void)
+{
+ PUThread *thread;
+ PUThreadInfo *thread_info;
+ struct Task *task;
+ PDestroyFunc dest_func;
+ ppointer dest_data;
+ pboolean need_pass;
+ pint i;
+ pint clean_counter;
+
+ /* Wait for outer routine to finish data initialization */
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ task = IExec->FindTask (NULL);
+ thread = (PUThread *) (task->tc_UserData);
+ thread_info = pp_uthread_find_thread_info (task);
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ IExec->SetTaskPri (task, pp_uthread_get_amiga_priority (thread->base.prio));
+
+ if (!setjmp (thread_info->jmpbuf))
+ thread->proxy (thread);
+
+ /* Clean up TLS values */
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ need_pass = TRUE;
+ clean_counter = 0;
+
+ while (need_pass && clean_counter < PUTHREAD_AMIGA_MAX_CLEANS) {
+ need_pass = FALSE;
+
+ for (i = 0; i < PUTHREAD_AMIGA_MAX_TLS_KEYS; ++i) {
+ if (pp_uthread_tls_keys[i].in_use == TRUE) {
+ dest_func = pp_uthread_tls_keys[i].free_func;
+ dest_data = thread_info->tls_values[i];
+
+ if (dest_func != NULL && dest_data != NULL) {
+ /* Destructor may do some trick with TLS as well */
+ thread_info->tls_values[i] = NULL;
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ (dest_func) (dest_data);
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ need_pass = TRUE;
+ }
+ }
+ }
+
+ ++clean_counter;
+ }
+
+ pp_uthread_list = p_list_remove (pp_uthread_list, thread_info);
+
+ p_free (thread_info);
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ /* Signal to possible waiter */
+
+ p_cond_variable_broadcast (thread->join_cond);
+}
+
+void
+p_uthread_init_internal (void)
+{
+ if (P_LIKELY (pp_uthread_glob_mutex == NULL)) {
+ pp_uthread_glob_mutex = p_mutex_new ();
+ pp_uthread_list = NULL;
+ pp_uthread_last_id = 0;
+
+ memset (pp_uthread_tls_keys, 0, sizeof (PUThreadTLSKey) * PUTHREAD_AMIGA_MAX_TLS_KEYS);
+ }
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+ PList *cur_list;
+ PUThreadInfo *thread_info;
+ PDestroyFunc dest_func;
+ ppointer dest_data;
+ pboolean need_pass;
+ pint i;
+ pint clean_counter;
+
+ /* Perform destructors */
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ need_pass = TRUE;
+ clean_counter = 0;
+
+ while (need_pass && clean_counter < PUTHREAD_AMIGA_MAX_CLEANS) {
+ need_pass = FALSE;
+
+ for (i = 0; i < PUTHREAD_AMIGA_MAX_TLS_KEYS; ++i) {
+ if (pp_uthread_tls_keys[i].in_use == FALSE)
+ continue;
+
+ dest_func = pp_uthread_tls_keys[i].free_func;
+
+ if (dest_func == NULL)
+ continue;
+
+ for (cur_list = pp_uthread_list; cur_list != NULL; cur_list = cur_list->next) {
+ thread_info = (PUThreadInfo *) cur_list->data;
+ dest_data = thread_info->tls_values[i];
+
+ if (dest_data != NULL) {
+ /* Destructor may do some trick with TLS as well */
+
+ thread_info->tls_values[i] = NULL;
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ (dest_func) (dest_data);
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ need_pass = TRUE;
+ }
+ }
+ }
+ }
+
+ /* Clean the list */
+
+ p_list_foreach (pp_uthread_list, (PFunc) p_free, NULL);
+ p_list_free (pp_uthread_list);
+
+ pp_uthread_list = NULL;
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ if (P_LIKELY (pp_uthread_glob_mutex != NULL)) {
+ p_mutex_free (pp_uthread_glob_mutex);
+ pp_uthread_glob_mutex = NULL;
+ }
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ if (thread->join_cond != NULL)
+ p_cond_variable_free (thread->join_cond);
+
+ p_free (thread);
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+ PUThreadInfo *thread_info;
+ struct Task *task;
+ pint task_id;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->join_cond = p_cond_variable_new ()) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate condvar");
+ p_uthread_free_internal (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((thread_info = p_malloc0 (sizeof (PUThreadInfo))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory (2)");
+ p_uthread_free_internal (ret);
+ return NULL;
+ }
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ task_id = pp_uthread_find_next_id ();
+
+ if (P_UNLIKELY (task_id == -1)) {
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ P_ERROR ("PUThread::p_uthread_create_internal: no free thread slots left");
+ p_uthread_free_internal (ret);
+ p_free (thread_info);
+ return NULL;
+ }
+
+ ret->proxy = func;
+ ret->base.prio = prio;
+ ret->base.joinable = joinable;
+
+ if (stack_size < PUTHREAD_AMIGA_MIN_STACK)
+ stack_size = PUTHREAD_AMIGA_MIN_STACK;
+
+ task = (struct Task *) IDOS->CreateNewProcTags (NP_Entry, pp_uthread_amiga_proxy,
+ NP_StackSize, stack_size,
+ NP_UserData, ret,
+ NP_Child, TRUE,
+ TAG_END);
+
+ if (P_UNLIKELY (task == NULL)) {
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ P_ERROR ("PUThread::p_uthread_create_internal: CreateTaskTags() failed");
+ p_uthread_free_internal (ret);
+ p_free (thread_info);
+ return NULL;
+ }
+
+ thread_info->task = task;
+ thread_info->id = task_id;
+
+ pp_uthread_list = p_list_append (pp_uthread_list, thread_info);
+
+ ret->task = task;
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ PUThreadInfo *thread_info;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ thread_info = pp_uthread_find_thread_info (IExec->FindTask (NULL));
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ if (P_UNLIKELY (thread_info == NULL)) {
+ P_WARNING ("PUThread::p_uthread_exit_internal: trying to exit from foreign thread");
+ return;
+ }
+
+ longjmp (thread_info->jmpbuf, 1);
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ PUThreadInfo *thread_info;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ thread_info = pp_uthread_find_thread_info (thread->task);
+
+ if (thread_info == NULL) {
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ return;
+ }
+
+ p_cond_variable_wait (thread->join_cond, pp_uthread_glob_mutex);
+ p_mutex_unlock (pp_uthread_glob_mutex);
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ struct Task *task = thread->task;
+
+ task->tc_Node.ln_Name = thread->base.name;
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ BYTE old_prio;
+ struct Task *task;
+
+ task = IExec->FindTask (NULL);
+
+ old_prio = IExec->SetTaskPri (task, -10);
+ IExec->SetTaskPri (task, old_prio);
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ IExec->SetTaskPri (thread->task, pp_uthread_get_amiga_priority (prio));
+
+ thread->base.prio = prio;
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ PUThreadInfo *thread_info;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ thread_info = pp_uthread_find_or_create_thread_info (IExec->FindTask (NULL));
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ if (P_UNLIKELY (thread_info == NULL))
+ P_WARNING ("PUThread::p_uthread_current_id: failed to integrate foreign thread");
+
+ return (thread_info == NULL) ? NULL : (P_HANDLE) ((psize) thread_info->id);
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->key = -1;
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ PUThreadInfo *thread_info;
+ puthread_key_t tls_key;
+ ppointer value = NULL;
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((tls_key = pp_uthread_get_tls_key (key)) == -1))
+ return NULL;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ thread_info = pp_uthread_find_thread_info (IExec->FindTask (NULL));
+
+ if (P_LIKELY (thread_info != NULL))
+ value = thread_info->tls_values[tls_key];
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+
+ return value;
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ PUThreadInfo *thread_info;
+ puthread_key_t tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key != -1)) {
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ thread_info = pp_uthread_find_or_create_thread_info (IExec->FindTask (NULL));
+
+ if (P_LIKELY (thread_info != NULL)) {
+ if (P_LIKELY (pp_uthread_tls_keys[tls_key].in_use == TRUE))
+ thread_info->tls_values[tls_key] = value;
+ }
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+ }
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ PUThreadInfo *thread_info;
+ puthread_key_t tls_key;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key == -1))
+ return;
+
+ p_mutex_lock (pp_uthread_glob_mutex);
+
+ if (P_LIKELY (pp_uthread_tls_keys[tls_key].in_use == TRUE)) {
+ thread_info = pp_uthread_find_or_create_thread_info (IExec->FindTask (NULL));
+
+ if (P_LIKELY (thread_info != NULL)) {
+ old_value = thread_info->tls_values[tls_key];
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ thread_info->tls_values[tls_key] = value;
+ }
+ }
+
+ p_mutex_unlock (pp_uthread_glob_mutex);
+}
diff --git a/3rdparty/plibsys/src/puthread-atheos.c b/3rdparty/plibsys/src/puthread-atheos.c
new file mode 100644
index 0000000..8d33ec5
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-atheos.c
@@ -0,0 +1,317 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <atheos/threads.h>
+#include <atheos/tld.h>
+
+typedef thread_id puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+};
+
+struct PUThreadKey_ {
+ pint key;
+ PDestroyFunc free_func;
+};
+
+static pint pp_uthread_get_atheos_priority (PUThreadPriority prio);
+static pint pp_uthread_get_tls_key (PUThreadKey *key);
+
+static pint
+pp_uthread_get_atheos_priority (PUThreadPriority prio)
+{
+ switch (prio) {
+ case P_UTHREAD_PRIORITY_INHERIT:
+ {
+ thread_info thr_info;
+
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ if (P_UNLIKELY (get_thread_info (get_thread_id (NULL), &thr_info) != 0)) {
+ P_WARNING ("PUThread::pp_uthread_get_atheos_priority: failed to get thread info");
+ return NORMAL_PRIORITY;
+ } else
+ return thr_info.ti_priority;
+ }
+
+ case P_UTHREAD_PRIORITY_IDLE:
+ return IDLE_PRIORITY;
+ case P_UTHREAD_PRIORITY_LOWEST:
+ return LOW_PRIORITY / 2;
+ case P_UTHREAD_PRIORITY_LOW:
+ return LOW_PRIORITY;
+ case P_UTHREAD_PRIORITY_NORMAL:
+ return NORMAL_PRIORITY;
+ case P_UTHREAD_PRIORITY_HIGH:
+ return DISPLAY_PRIORITY;
+ case P_UTHREAD_PRIORITY_HIGHEST:
+ return URGENT_DISPLAY_PRIORITY;
+ case P_UTHREAD_PRIORITY_TIMECRITICAL:
+ return REALTIME_PRIORITY;
+ }
+}
+
+static pint
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ pint thread_key;
+
+ thread_key = p_atomic_int_get ((const volatile pint *) &key->key);
+
+ if (P_LIKELY (thread_key >= 0))
+ return thread_key;
+
+ if (P_UNLIKELY ((thread_key = alloc_tld (key->free_func)) < 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: alloc_tld() failed");
+ return -1;
+ }
+
+ if (P_UNLIKELY (p_atomic_int_compare_and_exchange ((volatile pint *) &key->key,
+ -1,
+ thread_key) == FALSE)) {
+ if (P_UNLIKELY (free_tld (thread_key) != 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: free_tld() failed");
+ return -1;
+ }
+
+ thread_key = key->key;
+ }
+
+ return thread_key;
+}
+
+void
+p_uthread_init_internal (void)
+{
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ if (P_UNLIKELY ((ret->hdl = spawn_thread ("",
+ func,
+ pp_uthread_get_atheos_priority (prio),
+ stack_size,
+ ret)) < 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: spawn_thread() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (resume_thread (ret->hdl) != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: resume_thread() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+ ret->base.prio = prio;
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ exit_thread (0);
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ wait_for_thread (thread->hdl);
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ pchar *thr_name = NULL;
+ psize namelen = 0;
+ pint res = 0;
+ pboolean is_alloc = FALSE;
+
+ thr_name = thread->base.name;
+ namelen = strlen (thr_name);
+
+ if (namelen > OS_NAME_LENGTH - 1) {
+ if (P_UNLIKELY ((thr_name = p_malloc0 (namelen + 1)) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_set_name_internal: failed to allocate memory");
+ return;
+ }
+
+ memcpy (thr_name, thread->base.name, OS_NAME_LENGTH - 1);
+
+ is_alloc = TRUE;
+ }
+
+ if (rename_thread (thread->hdl, thr_name) != 0)
+ P_WARNING ("PUThread::p_uthread_set_name_internal: failed to set thread system name");
+
+ if (is_alloc == TRUE)
+ p_free (thr_name);
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ sched_yield ();
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ set_thread_priority (thread->hdl, pp_uthread_get_atheos_priority (prio));
+
+ thread->base.prio = prio;
+
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) ((psize) get_thread_id (NULL));
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->key = -1;
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ pint tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key >= 0))
+ return get_tld (tls_key);
+
+ return NULL;
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ pint tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (tls_key >= 0)
+ set_tld (tls_key, value);
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ pint tls_key;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key < 0))
+ return;
+
+ old_value = get_tld (tls_key);
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ set_tld (tls_key, value);
+}
diff --git a/3rdparty/plibsys/src/puthread-beos.c b/3rdparty/plibsys/src/puthread-beos.c
new file mode 100644
index 0000000..1f49747
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-beos.c
@@ -0,0 +1,431 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "pmutex.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <kernel/OS.h>
+#include <kernel/scheduler.h>
+#include <support/TLS.h>
+
+typedef thread_id puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+ PUThreadFunc proxy;
+};
+
+struct PUThreadKey_ {
+ pint key;
+ PDestroyFunc free_func;
+};
+
+typedef struct PUThreadDestructor_ PUThreadDestructor;
+
+struct PUThreadDestructor_ {
+ pint key_idx;
+ PDestroyFunc free_func;
+ PUThreadDestructor *next;
+};
+
+static PUThreadDestructor * volatile pp_uthread_tls_destructors = NULL;
+
+static PMutex *pp_uthread_tls_mutex = NULL;
+
+static pint pp_uthread_get_beos_priority (PUThreadPriority prio);
+static pint pp_uthread_get_tls_key (PUThreadKey *key);
+static void pp_uthread_clean_destructors (void);
+static pint pp_uthread_beos_proxy (ppointer data);
+
+static pint
+pp_uthread_get_beos_priority (PUThreadPriority prio)
+{
+ switch (prio) {
+ case P_UTHREAD_PRIORITY_INHERIT:
+ {
+ thread_info thr_info;
+
+ memset (&thr_info, 0, sizeof (thr_info));
+
+ if (P_UNLIKELY (get_thread_info (find_thread (NULL), &thr_info) != B_OK)) {
+ P_WARNING ("PUThread::pp_uthread_get_beos_priority: failed to get thread info");
+ return B_NORMAL_PRIORITY;
+ } else
+ return thr_info.priority;
+ }
+
+ case P_UTHREAD_PRIORITY_IDLE:
+ return B_LOW_PRIORITY;
+ case P_UTHREAD_PRIORITY_LOWEST:
+ return B_NORMAL_PRIORITY / 4;
+ case P_UTHREAD_PRIORITY_LOW:
+ return B_NORMAL_PRIORITY / 2;
+ case P_UTHREAD_PRIORITY_NORMAL:
+ return B_NORMAL_PRIORITY;
+ case P_UTHREAD_PRIORITY_HIGH:
+ return B_DISPLAY_PRIORITY;
+ case P_UTHREAD_PRIORITY_HIGHEST:
+ return B_URGENT_DISPLAY_PRIORITY;
+ case P_UTHREAD_PRIORITY_TIMECRITICAL:
+ return B_REAL_TIME_PRIORITY;
+ }
+}
+
+static pint
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ pint thread_key;
+
+ thread_key = p_atomic_int_get ((const volatile pint *) &key->key);
+
+ if (P_LIKELY (thread_key >= 0))
+ return thread_key;
+
+ p_mutex_lock (pp_uthread_tls_mutex);
+
+ thread_key = key->key;
+
+ if (P_LIKELY (thread_key == -1)) {
+ PUThreadDestructor *destr = NULL;
+
+ if (key->free_func != NULL) {
+ if (P_UNLIKELY ((destr = p_malloc0 (sizeof (PUThreadDestructor))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: failed to allocate memory");
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return -1;
+ }
+ }
+
+ if (P_UNLIKELY ((thread_key = tls_allocate ()) < 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: tls_allocate() failed");
+ p_free (destr);
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return -1;
+ }
+
+ if (destr != NULL) {
+ destr->key_idx = thread_key;
+ destr->free_func = key->free_func;
+ destr->next = pp_uthread_tls_destructors;
+
+ /* At the same time thread exit could be performed at there is no
+ * lock for the global destructor list */
+ if (P_UNLIKELY (p_atomic_pointer_compare_and_exchange ((void * volatile *) &pp_uthread_tls_destructors,
+ (void *) destr->next,
+ (void *) destr) == FALSE)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: p_atomic_pointer_compare_and_exchange() failed");
+ p_free (destr);
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return -1;
+ }
+ }
+
+ key->key = thread_key;
+ }
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+
+ return thread_key;
+}
+
+static void
+pp_uthread_clean_destructors (void)
+{
+ pboolean was_called;
+
+ do {
+ PUThreadDestructor *destr;
+
+ was_called = FALSE;
+
+ destr = (PUThreadDestructor *) p_atomic_pointer_get ((const void * volatile *) &pp_uthread_tls_destructors);
+
+ while (destr != NULL) {
+ ppointer value;
+
+ value = tls_get (destr->key_idx);
+
+ if (value != NULL && destr->free_func != NULL) {
+ tls_set (destr->key_idx, NULL);
+ destr->free_func (value);
+ was_called = TRUE;
+ }
+
+ destr = destr->next;
+ }
+ } while (was_called);
+}
+
+static pint
+pp_uthread_beos_proxy (ppointer data)
+{
+ PUThread *thread = data;
+
+ thread->proxy (thread);
+
+ pp_uthread_clean_destructors ();
+
+ return 0;
+}
+
+void
+p_uthread_init_internal (void)
+{
+ if (P_LIKELY (pp_uthread_tls_mutex == NULL))
+ pp_uthread_tls_mutex = p_mutex_new ();
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+ PUThreadDestructor *destr;
+
+ pp_uthread_clean_destructors ();
+
+ destr = pp_uthread_tls_destructors;
+
+ while (destr != NULL) {
+ PUThreadDestructor *next_destr = destr->next;
+
+ p_free (destr);
+ destr = next_destr;
+ }
+
+ pp_uthread_tls_destructors = NULL;
+
+ if (P_LIKELY (pp_uthread_tls_mutex != NULL)) {
+ p_mutex_free (pp_uthread_tls_mutex);
+ pp_uthread_tls_mutex = NULL;
+ }
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+
+ P_UNUSED (stack_size);
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->proxy = func;
+
+ if (P_UNLIKELY ((ret->hdl = spawn_thread ((thread_func) pp_uthread_beos_proxy,
+ "",
+ pp_uthread_get_beos_priority (prio),
+ ret)) < B_OK)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: spawn_thread() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (resume_thread (ret->hdl) != B_OK)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: resume_thread() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+ ret->base.prio = prio;
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ pp_uthread_clean_destructors ();
+ exit_thread (0);
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ status_t exit_value;
+
+ wait_for_thread (thread->hdl, &exit_value);
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ pchar *thr_name = NULL;
+ psize namelen = 0;
+ pint res = 0;
+ pboolean is_alloc = FALSE;
+
+ thr_name = thread->base.name;
+ namelen = strlen (thr_name);
+
+ if (namelen > B_OS_NAME_LENGTH - 1) {
+ if (P_UNLIKELY ((thr_name = p_malloc0 (namelen + 1)) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_set_name_internal: failed to allocate memory");
+ return;
+ }
+
+ memcpy (thr_name, thread->base.name, B_OS_NAME_LENGTH - 1);
+
+ is_alloc = TRUE;
+ }
+
+ if (rename_thread (thread->hdl, thr_name) != 0)
+ P_WARNING ("PUThread::p_uthread_set_name_internal: failed to set thread system name");
+
+ if (is_alloc == TRUE)
+ p_free (thr_name);
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ snooze ((bigtime_t) 0);
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ if (set_thread_priority (thread->hdl, pp_uthread_get_beos_priority (prio)) < B_OK) {
+ P_ERROR ("PUThread::p_uthread_create_internal: set_thread_priority() failed");
+ return FALSE;
+ }
+
+ thread->base.prio = prio;
+
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) ((psize) find_thread (NULL));
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->key = -1;
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ pint tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key >= 0))
+ return tls_get (tls_key);
+
+ return NULL;
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ pint tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (tls_key >= 0)
+ tls_set (tls_key, value);
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ pint tls_key;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key < 0))
+ return;
+
+ old_value = tls_get (tls_key);
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ tls_set (tls_key, value);
+}
diff --git a/3rdparty/plibsys/src/puthread-none.c b/3rdparty/plibsys/src/puthread-none.c
new file mode 100644
index 0000000..c2ecc75
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-none.c
@@ -0,0 +1,142 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <stdlib.h>
+
+struct PUThread_ {
+ pint hdl;
+};
+
+void
+p_uthread_init_internal (void)
+{
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ P_UNUSED (func);
+ P_UNUSED (joinable);
+ P_UNUSED (prio);
+ P_UNUSED (stack_size);
+
+ return NULL;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ P_UNUSED (thread);
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ P_UNUSED (thread);
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ P_UNUSED (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ P_UNUSED (thread);
+ P_UNUSED (prio);
+
+ return FALSE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) 0;
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ P_UNUSED (free_func);
+ return NULL;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ P_UNUSED (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ P_UNUSED (key);
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ P_UNUSED (key);
+ P_UNUSED (value);
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ P_UNUSED (key);
+ P_UNUSED (value);
+}
diff --git a/3rdparty/plibsys/src/puthread-os2.c b/3rdparty/plibsys/src/puthread-os2.c
new file mode 100644
index 0000000..8bb3731
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-os2.c
@@ -0,0 +1,458 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define INCL_DOSPROCESS
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <process.h>
+
+#ifdef P_DEBUG
+# undef P_DEBUG
+#endif
+
+#include "pmem.h"
+#include "patomic.h"
+#include "pmutex.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <stdlib.h>
+
+typedef TID puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+ PUThreadFunc proxy;
+};
+
+struct PUThreadKey_ {
+ PULONG key;
+ PDestroyFunc free_func;
+};
+
+typedef struct PUThreadDestructor_ PUThreadDestructor;
+
+struct PUThreadDestructor_ {
+ PULONG key;
+ PDestroyFunc free_func;
+ PUThreadDestructor *next;
+};
+
+static PUThreadDestructor * volatile pp_uthread_tls_destructors = NULL;
+static PMutex *pp_uthread_tls_mutex = NULL;
+
+static void pp_uthread_get_os2_priority (PUThreadPriority prio, PULONG thr_class, PLONG thr_level);
+static PULONG pp_uthread_get_tls_key (PUThreadKey *key);
+static void pp_uthread_clean_destructors (void);
+static void pp_uthread_os2_proxy (ppointer data);
+
+static void
+pp_uthread_get_os2_priority (PUThreadPriority prio, PULONG thr_class, PLONG thr_level)
+{
+ switch (prio) {
+ case P_UTHREAD_PRIORITY_INHERIT:
+ {
+ APIRET ulrc;
+ PTIB ptib = NULL;
+
+ if (P_UNLIKELY (DosGetInfoBlocks (&ptib, NULL) != NO_ERROR)) {
+ P_WARNING ("PUThread::pp_uthread_get_os2_priority: DosGetInfoBlocks() failed");
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = 0;
+ } else {
+ *thr_class = ((ptib->tib_ptib2->tib2_ulpri) >> 8) & 0x00FF;
+ *thr_level = (ptib->tib_ptib2->tib2_ulpri) & 0x001F;
+ }
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_IDLE:
+ {
+ *thr_class = PRTYC_IDLETIME;
+ *thr_level = 0;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_LOWEST:
+ {
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = PRTYD_MINIMUM;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_LOW:
+ {
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = PRTYD_MINIMUM / 2;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_NORMAL:
+ {
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = 0;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_HIGH:
+ {
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = PRTYD_MAXIMUM / 2;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_HIGHEST:
+ {
+ *thr_class = PRTYC_REGULAR;
+ *thr_level = PRTYD_MAXIMUM;
+
+ return;
+ }
+ case P_UTHREAD_PRIORITY_TIMECRITICAL:
+ {
+ *thr_class = PRTYC_TIMECRITICAL;
+ *thr_level = 0;
+
+ return;
+ }
+ }
+}
+
+static PULONG
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ PULONG thread_key;
+
+ thread_key = (PULONG) p_atomic_pointer_get ((ppointer) &key->key);
+
+ if (P_LIKELY (thread_key != NULL))
+ return thread_key;
+
+ p_mutex_lock (pp_uthread_tls_mutex);
+
+ thread_key = key->key;
+
+ if (P_LIKELY (thread_key == NULL)) {
+ PUThreadDestructor *destr = NULL;
+
+ if (key->free_func != NULL) {
+ if (P_UNLIKELY ((destr = p_malloc0 (sizeof (PUThreadDestructor))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: failed to allocate memory");
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return NULL;
+ }
+ }
+
+ if (P_UNLIKELY (DosAllocThreadLocalMemory (1, &thread_key) != NO_ERROR)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: DosAllocThreadLocalMemory() failed");
+ p_free (destr);
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return NULL;
+ }
+
+ if (destr != NULL) {
+ destr->key = thread_key;
+ destr->free_func = key->free_func;
+ destr->next = pp_uthread_tls_destructors;
+
+ /* At the same time thread exit could be performed at there is no
+ * lock for the global destructor list */
+ if (P_UNLIKELY (p_atomic_pointer_compare_and_exchange ((void * volatile *) &pp_uthread_tls_destructors,
+ (void *) destr->next,
+ (void *) destr) == FALSE)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: p_atomic_pointer_compare_and_exchange() failed");
+
+ if (P_UNLIKELY (DosFreeThreadLocalMemory (thread_key) != NO_ERROR))
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: DosFreeThreadLocalMemory() failed");
+
+ p_free (destr);
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return NULL;
+ }
+ }
+
+ key->key = thread_key;
+ }
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+
+ return thread_key;
+}
+
+static void
+pp_uthread_clean_destructors (void)
+{
+ pboolean was_called;
+
+ do {
+ PUThreadDestructor *destr;
+
+ was_called = FALSE;
+
+ destr = (PUThreadDestructor *) p_atomic_pointer_get ((const void * volatile *) &pp_uthread_tls_destructors);
+
+ while (destr != NULL) {
+ PULONG value;
+
+ value = destr->key;
+
+ if (value != NULL && ((ppointer) *value) != NULL && destr->free_func != NULL) {
+ *destr->key = (ULONG) NULL;
+ destr->free_func ((ppointer) *value);
+ was_called = TRUE;
+ }
+
+ destr = destr->next;
+ }
+ } while (was_called);
+}
+
+static void
+pp_uthread_os2_proxy (ppointer data)
+{
+ PUThread *thread = data;
+
+ thread->proxy (thread);
+
+ pp_uthread_clean_destructors ();
+}
+
+void
+p_uthread_init_internal (void)
+{
+ if (P_LIKELY (pp_uthread_tls_mutex == NULL))
+ pp_uthread_tls_mutex = p_mutex_new ();
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+ PUThreadDestructor *destr;
+
+ pp_uthread_clean_destructors ();
+
+ destr = pp_uthread_tls_destructors;
+
+ while (destr != NULL) {
+ PUThreadDestructor *next_destr = destr->next;
+
+ p_free (destr);
+ destr = next_destr;
+ }
+
+ pp_uthread_tls_destructors = NULL;
+
+ if (P_LIKELY (pp_uthread_tls_mutex != NULL)) {
+ p_mutex_free (pp_uthread_tls_mutex);
+ pp_uthread_tls_mutex = NULL;
+ }
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+ ret->proxy = func;
+
+ if (P_UNLIKELY ((ret->hdl = _beginthread ((void (*) (void *)) pp_uthread_os2_proxy,
+ NULL,
+ (puint) stack_size,
+ ret)) <= 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: _beginthread() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.prio = P_UTHREAD_PRIORITY_INHERIT;
+ p_uthread_set_priority (ret, prio);
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ pp_uthread_clean_destructors ();
+ _endthread ();
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ APIRET ulrc;
+
+ while ((ulrc = DosWaitThread (&thread->hdl, DCWW_WAIT)) == ERROR_INTERRUPT)
+ ;
+
+ if (P_UNLIKELY (ulrc != NO_ERROR && ulrc != ERROR_INVALID_THREADID))
+ P_ERROR ("PUThread::p_uthread_wait_internal: DosWaitThread() failed");
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ P_UNUSED (thread);
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ DosSleep (0);
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ APIRET ulrc;
+ PTIB ptib = NULL;
+ LONG cur_level;
+ LONG new_level;
+ ULONG new_class;
+
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (DosGetInfoBlocks (&ptib, NULL) != NO_ERROR)) {
+ P_WARNING ("PUThread::p_uthread_set_priority: DosGetInfoBlocks() failed");
+ return FALSE;
+ }
+
+ cur_level = (ptib->tib_ptib2->tib2_ulpri) & 0x001F;
+
+ pp_uthread_get_os2_priority (prio, &new_class, &new_level);
+
+ if (P_UNLIKELY (DosSetPriority (PRTYS_THREAD, new_class, new_level - cur_level, 0) != NO_ERROR)) {
+ P_WARNING ("PUThread::p_uthread_set_priority: DosSetPriority() failed");
+ return FALSE;
+ }
+
+ thread->base.prio = prio;
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) (_gettid ());
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ PULONG tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((tls_key = pp_uthread_get_tls_key (key)) == NULL))
+ return NULL;
+
+ return (ppointer) *tls_key;
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ PULONG tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key != NULL))
+ *tls_key = (ULONG) value;
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ PULONG tls_key;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key == NULL))
+ return;
+
+ old_value = (ppointer) *tls_key;
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ *tls_key = (ULONG) value;
+}
diff --git a/3rdparty/plibsys/src/puthread-posix.c b/3rdparty/plibsys/src/puthread-posix.c
new file mode 100644
index 0000000..90e14d5
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-posix.c
@@ -0,0 +1,580 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#ifdef P_OS_SCO
+# include "pmutex.h"
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+/* On some OS like OpenBSD it must follow <pthread.h> */
+#ifdef PLIBSYS_NEED_PTHREAD_NP_H
+# include <pthread_np.h>
+#endif
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+# ifndef P_OS_VMS
+# include <sched.h>
+# endif
+#endif
+
+#ifdef PLIBSYS_HAS_PTHREAD_PRCTL
+# include <sys/prctl.h>
+# include <linux/prctl.h>
+#endif
+
+#ifdef P_OS_QNX6
+# include <sys/neutrino.h>
+#endif
+
+#ifdef P_OS_HAIKU
+# include <kernel/OS.h>
+#endif
+
+/* Some systems without native pthreads may lack some of the constants,
+ * leave them zero as we are not going to use them anyway */
+
+#ifndef PTHREAD_CREATE_JOINABLE
+# define PTHREAD_CREATE_JOINABLE 0
+#endif
+
+#ifndef PTHREAD_CREATE_DETACHED
+# define PTHREAD_CREATE_DETACHED 0
+#endif
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+# ifndef PTHREAD_INHERIT_SCHED
+# define PTHREAD_INHERIT_SCHED 0
+# endif
+
+# ifndef PTHREAD_EXPLICIT_SCHED
+# define PTHREAD_EXPLICIT_SCHED 0
+# endif
+
+/* Old Linux kernels may lack a definition */
+# if defined (P_OS_LINUX) && !defined (SCHED_IDLE)
+# define SCHED_IDLE 5
+# endif
+#endif
+
+/* Max length of a thead name */
+#if defined(P_OS_LINUX)
+# define PUTHREAD_MAX_NAME 16
+#elif defined(P_OS_NETBSD)
+# define PUTHREAD_MAX_NAME PTHREAD_MAX_NAMELEN_NP
+#elif defined(P_OS_DRAGONFLY)
+# define PUTHREAD_MAX_NAME 16
+#elif defined(P_OS_SOLARIS)
+# define PUTHREAD_MAX_NAME 32
+#elif defined(P_OS_TRU64)
+# define PUTHREAD_MAX_NAME 32
+#elif defined(P_OS_VMS)
+# define PUTHREAD_MAX_NAME 32
+#elif defined(P_OS_QNX6)
+# define PUTHREAD_MAX_NAME _NTO_THREAD_NAME_MAX
+#elif defined(P_OS_HAIKU)
+# define PUTHREAD_MAX_NAME 32
+#endif
+
+typedef pthread_t puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+};
+
+struct PUThreadKey_ {
+ pthread_key_t *key;
+ PDestroyFunc free_func;
+};
+
+#ifdef P_OS_SCO
+static PMutex *pp_uthread_tls_mutex = NULL;
+#endif
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+static pboolean pp_uthread_get_unix_priority (PUThreadPriority prio, int *sched_policy, int *sched_priority);
+#endif
+
+static pthread_key_t * pp_uthread_get_tls_key (PUThreadKey *key);
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+static pboolean
+pp_uthread_get_unix_priority (PUThreadPriority prio, int *sched_policy, int *sched_priority)
+{
+ pint lowBound, upperBound;
+ pint prio_min, prio_max;
+ pint native_prio;
+
+#ifdef SCHED_IDLE
+ if (prio == P_UTHREAD_PRIORITY_IDLE) {
+ *sched_policy = SCHED_IDLE;
+ *sched_priority = 0;
+ return TRUE;
+ }
+
+ lowBound = (pint) P_UTHREAD_PRIORITY_LOWEST;
+#else
+ lowBound = (pint) P_UTHREAD_PRIORITY_IDLE;
+#endif
+ upperBound = (pint) P_UTHREAD_PRIORITY_TIMECRITICAL;
+
+ prio_min = sched_get_priority_min (*sched_policy);
+ prio_max = sched_get_priority_max (*sched_policy);
+
+ if (P_UNLIKELY (prio_min == -1 || prio_max == -1))
+ return FALSE;
+
+ native_prio = ((pint) prio - lowBound) * (prio_max - prio_min) / upperBound + prio_min;
+
+ if (P_UNLIKELY (native_prio > prio_max))
+ native_prio = prio_max;
+
+ if (P_UNLIKELY (native_prio < prio_min))
+ native_prio = prio_min;
+
+ *sched_priority = native_prio;
+
+ return TRUE;
+}
+#endif
+
+static pthread_key_t *
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ pthread_key_t *thread_key;
+
+ thread_key = (pthread_key_t *) p_atomic_pointer_get ((ppointer) &key->key);
+
+ if (P_LIKELY (thread_key != NULL))
+ return thread_key;
+
+#ifdef P_OS_SCO
+ p_mutex_lock (pp_uthread_tls_mutex);
+
+ thread_key = key->key;
+
+ if (P_LIKELY (thread_key == NULL)) {
+#endif
+ if (P_UNLIKELY ((thread_key = p_malloc0 (sizeof (pthread_key_t))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: failed to allocate memory");
+#ifdef P_OS_SCO
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pthread_key_create (thread_key, key->free_func) != 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: pthread_key_create() failed");
+ p_free (thread_key);
+#ifdef P_OS_SCO
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+ return NULL;
+ }
+
+#ifndef P_OS_SCO
+ if (P_UNLIKELY (p_atomic_pointer_compare_and_exchange ((ppointer) &key->key,
+ NULL,
+ (ppointer) thread_key) == FALSE)) {
+ if (P_UNLIKELY (pthread_key_delete (*thread_key) != 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: pthread_key_delete() failed");
+ p_free (thread_key);
+ return NULL;
+ }
+
+ p_free (thread_key);
+
+ thread_key = key->key;
+ }
+#else
+ key->key = thread_key;
+ }
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+
+ return thread_key;
+}
+
+void
+p_uthread_init_internal (void)
+{
+#ifdef P_OS_SCO
+ if (P_LIKELY (pp_uthread_tls_mutex == NULL))
+ pp_uthread_tls_mutex = p_mutex_new ();
+#endif
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+#ifdef P_OS_SCO
+ if (P_LIKELY (pp_uthread_tls_mutex != NULL)) {
+ p_mutex_free (pp_uthread_tls_mutex);
+ pp_uthread_tls_mutex = NULL;
+ }
+#endif
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+ pthread_attr_t attr;
+ pint create_code;
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+ struct sched_param sched;
+ pint native_prio;
+ pint sched_policy;
+#endif
+
+#if defined (PLIBSYS_HAS_POSIX_STACKSIZE) && defined (_SC_THREAD_STACK_MIN)
+ plong min_stack;
+#endif
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+
+ if (P_UNLIKELY (pthread_attr_init (&attr) != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: pthread_attr_init() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (pthread_attr_setdetachstate (&attr,
+ joinable ? PTHREAD_CREATE_JOINABLE
+ : PTHREAD_CREATE_DETACHED) != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: pthread_attr_setdetachstate() failed");
+ pthread_attr_destroy (&attr);
+ p_free (ret);
+ return NULL;
+ }
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+ if (prio == P_UTHREAD_PRIORITY_INHERIT) {
+ if (P_UNLIKELY (pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED) != 0))
+ P_WARNING ("PUThread::p_uthread_create_internal: pthread_attr_setinheritsched() failed");
+ } else {
+ if (P_LIKELY (pthread_attr_getschedpolicy (&attr, &sched_policy) == 0)) {
+ if (P_LIKELY (pp_uthread_get_unix_priority (prio,
+ &sched_policy,
+ &native_prio) == TRUE)) {
+ memset (&sched, 0, sizeof (sched));
+ sched.sched_priority = native_prio;
+
+ if (P_LIKELY (pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED) != 0 ||
+ pthread_attr_setschedpolicy (&attr, sched_policy) != 0 ||
+ pthread_attr_setschedparam (&attr, &sched) != 0))
+ P_WARNING ("PUThread::p_uthread_create_internal: failed to set priority");
+ } else
+ P_WARNING ("PUThread::p_uthread_create_internal: pp_uthread_get_unix_priority() failed");
+ } else
+ P_WARNING ("PUThread::p_uthread_create_internal: pthread_attr_getschedpolicy() failed");
+ }
+#endif
+
+#ifdef PLIBSYS_HAS_POSIX_STACKSIZE
+# ifdef _SC_THREAD_STACK_MIN
+ if (stack_size > 0) {
+ min_stack = (plong) sysconf (_SC_THREAD_STACK_MIN);
+
+ if (P_LIKELY (min_stack > 0)) {
+ if (P_UNLIKELY (stack_size < (psize) min_stack))
+ stack_size = (psize) min_stack;
+ } else
+ P_WARNING ("PUThread::p_uthread_create_internal: sysconf() with _SC_THREAD_STACK_MIN failed");
+
+ if (P_UNLIKELY (pthread_attr_setstacksize (&attr, stack_size) != 0))
+ P_WARNING ("PUThread::p_uthread_create_internal: pthread_attr_setstacksize() failed");
+ }
+# endif
+#endif
+
+ create_code = pthread_create (&ret->hdl, &attr, func, ret);
+
+#ifdef EPERM
+ if (create_code == EPERM) {
+# ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+ pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED);
+# endif
+ create_code = pthread_create (&ret->hdl, &attr, func, ret);
+ }
+#endif
+
+ if (P_UNLIKELY (create_code != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: pthread_create() failed");
+ pthread_attr_destroy (&attr);
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.prio = prio;
+ pthread_attr_destroy (&attr);
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ pthread_exit (P_INT_TO_POINTER (0));
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ if (P_UNLIKELY (pthread_join (thread->hdl, NULL) != 0))
+ P_ERROR ("PUThread::p_uthread_wait_internal: pthread_join() failed");
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ pchar *thr_name = NULL;
+ pint res = 0;
+ pboolean is_alloc = FALSE;
+#ifdef PUTHREAD_MAX_NAME
+ psize namelen = 0;
+#endif
+
+ thr_name = thread->base.name;
+
+#ifdef PUTHREAD_MAX_NAME
+ namelen = strlen (thr_name);
+
+ if (namelen > PUTHREAD_MAX_NAME - 1) {
+ if (P_UNLIKELY ((thr_name = p_malloc0 (namelen + 1)) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_set_name_internal: failed to allocate memory");
+ return;
+ }
+
+ memcpy (thr_name, thread->base.name, PUTHREAD_MAX_NAME - 1);
+
+ is_alloc = TRUE;
+ }
+#endif
+
+#if defined(PLIBSYS_HAS_PTHREAD_SETNAME)
+# if defined(P_OS_MAC)
+ if (thread->hdl != pthread_self ())
+ P_WARNING ("PUThread::p_uthread_set_name_internal: only calling thread is supported in macOS");
+ else
+ res = pthread_setname_np (thr_name);
+# elif defined(P_OS_NETBSD)
+ res = pthread_setname_np (thread->hdl, "%s", thr_name);
+# elif defined(P_OS_TRU64) || defined(P_OS_VMS)
+ res = pthread_setname_np (thread->hdl, thr_name, 0);
+# else
+ res = pthread_setname_np (thread->hdl, thr_name);
+# endif
+#elif defined(PLIBSYS_HAS_PTHREAD_SET_NAME)
+ pthread_set_name_np (thread->hdl, thr_name);
+#elif defined(PLIBSYS_HAS_PTHREAD_PRCTL)
+ if (thread->hdl != pthread_self ())
+ P_WARNING ("PUThread::p_uthread_set_name_internal: prctl() can be used on calling thread only");
+ else
+ res = prctl (PR_SET_NAME, thr_name, NULL, NULL, NULL);
+#elif defined(P_OS_HAIKU)
+ res = rename_thread (find_thread (NULL), thr_name);
+#endif
+
+ if (is_alloc == TRUE)
+ p_free (thr_name);
+
+ if (res != 0)
+ P_WARNING ("PUThread::p_uthread_set_name_internal: failed to set thread system name");
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ sched_yield ();
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+ struct sched_param sched;
+ pint policy;
+ pint native_prio;
+#endif
+
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+#ifdef PLIBSYS_HAS_POSIX_SCHEDULING
+ if (P_UNLIKELY (pthread_getschedparam (thread->hdl, &policy, &sched) != 0)) {
+ P_ERROR ("PUThread::p_uthread_set_priority: pthread_getschedparam() failed");
+ return FALSE;
+ }
+
+ if (P_UNLIKELY (pp_uthread_get_unix_priority (prio, &policy, &native_prio) == FALSE)) {
+ P_ERROR ("PUThread::p_uthread_set_priority: pp_uthread_get_unix_priority() failed");
+ return FALSE;
+ }
+
+ memset (&sched, 0, sizeof (sched));
+ sched.sched_priority = native_prio;
+
+ if (P_UNLIKELY (pthread_setschedparam (thread->hdl, policy, &sched) != 0)) {
+ P_ERROR ("PUThread::p_uthread_set_priority: pthread_setschedparam() failed");
+ return FALSE;
+ }
+#endif
+
+ thread->base.prio = prio;
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) ((psize) pthread_self ());
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ pthread_key_t *tls_key;
+#ifdef P_OS_SCO
+ ppointer value;
+#endif
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ if (P_UNLIKELY ((tls_key = pp_uthread_get_tls_key (key)) == NULL))
+ return NULL;
+
+#ifdef P_OS_SCO
+ if (P_UNLIKELY (pthread_getspecific (*tls_key, &value) != 0))
+ return NULL;
+
+ return value;
+#else
+ return pthread_getspecific (*tls_key);
+#endif
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ pthread_key_t *tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key != NULL)) {
+ if (P_UNLIKELY (pthread_setspecific (*tls_key, value) != 0))
+ P_ERROR ("PUThread::p_uthread_set_local: pthread_setspecific() failed");
+ }
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ pthread_key_t *tls_key;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key == NULL))
+ return;
+
+#ifdef P_OS_SCO
+ if (P_UNLIKELY (pthread_getspecific (*tls_key, &old_value) != 0))
+ return;
+#else
+ old_value = pthread_getspecific (*tls_key);
+#endif
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ if (P_UNLIKELY (pthread_setspecific (*tls_key, value) != 0))
+ P_ERROR ("PUThread::p_uthread_replace_local: pthread_setspecific() failed");
+}
diff --git a/3rdparty/plibsys/src/puthread-private.h b/3rdparty/plibsys/src/puthread-private.h
new file mode 100644
index 0000000..9b389d8
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-private.h
@@ -0,0 +1,53 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PUTHREAD_PRIVATE_H
+#define PLIBSYS_HEADER_PUTHREAD_PRIVATE_H
+
+#include "pmacros.h"
+#include "ptypes.h"
+#include "puthread.h"
+
+P_BEGIN_DECLS
+
+/** Base thread structure */
+typedef struct PUThreadBase_ {
+ pint ref_count; /**< Reference counter. */
+ pint ret_code; /**< Return code. */
+ pboolean ours; /**< Our thread flag. */
+ pboolean joinable; /**< Joinable flag. */
+ PUThreadFunc func; /**< Thread routine. */
+ ppointer data; /**< Thread input data. */
+ PUThreadPriority prio; /**< Thread priority. */
+ pchar *name; /**< Thread name */
+} PUThreadBase;
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PUTHREAD_PRIVATE_H */
diff --git a/3rdparty/plibsys/src/puthread-solaris.c b/3rdparty/plibsys/src/puthread-solaris.c
new file mode 100644
index 0000000..80f9f7b
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-solaris.c
@@ -0,0 +1,352 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "patomic.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#ifndef P_OS_UNIXWARE
+# include "pmutex.h"
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <thread.h>
+
+#ifdef P_OS_UNIXWARE
+# define PLIBSYS_THREAD_MIN_PRIO 0
+# define PLIBSYS_THREAD_MAX_PRIO 126
+#else
+# define PLIBSYS_THREAD_MIN_PRIO 0
+# define PLIBSYS_THREAD_MAX_PRIO 127
+#endif
+
+typedef thread_t puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+};
+
+struct PUThreadKey_ {
+ thread_key_t *key;
+ PDestroyFunc free_func;
+};
+
+#ifndef P_OS_UNIXWARE
+static PMutex *pp_uthread_tls_mutex = NULL;
+#endif
+
+static pint pp_uthread_get_unix_priority (PUThreadPriority prio);
+static thread_key_t * pp_uthread_get_tls_key (PUThreadKey *key);
+
+static pint
+pp_uthread_get_unix_priority (PUThreadPriority prio)
+{
+ pint lowBound, upperBound;
+
+ lowBound = (pint) P_UTHREAD_PRIORITY_IDLE;
+ upperBound = (pint) P_UTHREAD_PRIORITY_TIMECRITICAL;
+
+ return ((pint) prio - lowBound) *
+ (PLIBSYS_THREAD_MAX_PRIO - PLIBSYS_THREAD_MIN_PRIO) / upperBound +
+ PLIBSYS_THREAD_MIN_PRIO;
+}
+
+static thread_key_t *
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ thread_key_t *thread_key;
+
+ thread_key = (thread_key_t *) p_atomic_pointer_get ((ppointer) &key->key);
+
+ if (P_LIKELY (thread_key != NULL))
+ return thread_key;
+
+#ifndef P_OS_UNIXWARE
+ p_mutex_lock (pp_uthread_tls_mutex);
+
+ thread_key = key->key;
+
+ if (P_LIKELY (thread_key == NULL)) {
+#endif
+ if (P_UNLIKELY ((thread_key = p_malloc0 (sizeof (thread_key_t))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: failed to allocate memory");
+#ifndef P_OS_UNIXWARE
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+ return NULL;
+ }
+
+ if (P_UNLIKELY (thr_keycreate (thread_key, key->free_func) != 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: thr_keycreate() failed");
+ p_free (thread_key);
+#ifndef P_OS_UNIXWARE
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+ return NULL;
+ }
+#ifdef P_OS_UNIXWARE
+ if (P_UNLIKELY (p_atomic_pointer_compare_and_exchange ((ppointer) &key->key,
+ NULL,
+ (ppointer) thread_key) == FALSE)) {
+ if (P_UNLIKELY (thr_keydelete (*thread_key) != 0)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: thr_keydelete() failed");
+ p_free (thread_key);
+ return NULL;
+ }
+
+ p_free (thread_key);
+
+ thread_key = key->key;
+ }
+#else
+ key->key = thread_key;
+ }
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+#endif
+
+ return thread_key;
+}
+
+void
+p_uthread_init_internal (void)
+{
+#ifndef P_OS_UNIXWARE
+ if (P_LIKELY (pp_uthread_tls_mutex == NULL))
+ pp_uthread_tls_mutex = p_mutex_new ();
+#endif
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+#ifndef P_OS_UNIXWARE
+ if (P_LIKELY (pp_uthread_tls_mutex != NULL)) {
+ p_mutex_free (pp_uthread_tls_mutex);
+ pp_uthread_tls_mutex = NULL;
+ }
+#endif
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+ pint32 flags;
+ psize min_stack;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ if (stack_size > 0) {
+#ifdef P_OS_UNIXWARE
+ min_stack = thr_minstack ();
+#else
+ min_stack = thr_min_stack ();
+#endif
+
+ if (P_UNLIKELY (stack_size < min_stack))
+ stack_size = min_stack;
+ }
+
+ flags = THR_SUSPENDED;
+ flags |= joinable ? 0 : THR_DETACHED;
+
+ if (P_UNLIKELY (thr_create (NULL, stack_size, func, ret, flags, &ret->hdl) != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: thr_create() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ if (P_UNLIKELY (thr_setprio (ret->hdl, pp_uthread_get_unix_priority (prio)) != 0))
+ P_WARNING ("PUThread::p_uthread_create_internal: thr_setprio() failed");
+
+ if (P_UNLIKELY (thr_continue (ret->hdl) != 0)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: thr_continue() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+ ret->base.prio = prio;
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ thr_exit (P_INT_TO_POINTER (0));
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ if (P_UNLIKELY (thr_join (thread->hdl, NULL, NULL) != 0))
+ P_ERROR ("PUThread::p_uthread_wait_internal: thr_join() failed");
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ P_UNUSED (thread);
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ thr_yield ();
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ if (P_UNLIKELY (thr_setprio (thread->hdl, pp_uthread_get_unix_priority (prio)) != 0)) {
+ P_WARNING ("PUThread::p_uthread_set_priority: thr_setprio() failed");
+ return FALSE;
+ }
+
+ thread->base.prio = prio;
+
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) ((psize) thr_self ());
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ thread_key_t *tls_key;
+ ppointer ret = NULL;
+
+ if (P_UNLIKELY (key == NULL))
+ return ret;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key != NULL)) {
+ if (P_UNLIKELY (thr_getspecific (*tls_key, &ret) != 0))
+ P_ERROR ("PUThread::p_uthread_get_local: thr_getspecific() failed");
+ }
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ thread_key_t *tls_key;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_key != NULL)) {
+ if (P_UNLIKELY (thr_setspecific (*tls_key, value) != 0))
+ P_ERROR ("PUThread::p_uthread_set_local: thr_setspecific() failed");
+ }
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ thread_key_t *tls_key;
+ ppointer old_value = NULL;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_key = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_key == NULL))
+ return;
+
+ if (P_UNLIKELY (thr_getspecific (*tls_key, &old_value) != 0)) {
+ P_ERROR ("PUThread::p_uthread_replace_local: thr_getspecific() failed");
+ return;
+ }
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ if (P_UNLIKELY (thr_setspecific (*tls_key, value) != 0))
+ P_ERROR ("PUThread::p_uthread_replace_local: thr_setspecific() failed");
+}
diff --git a/3rdparty/plibsys/src/puthread-win.c b/3rdparty/plibsys/src/puthread-win.c
new file mode 100644
index 0000000..57604fd
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread-win.c
@@ -0,0 +1,511 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pmem.h"
+#include "pmutex.h"
+#include "patomic.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#include <process.h>
+
+typedef HRESULT (WINAPI * PWin32SetThreadDescription) (HANDLE hThread, PCWSTR lpThreadDescription);
+typedef HANDLE puthread_hdl;
+
+struct PUThread_ {
+ PUThreadBase base;
+ puthread_hdl hdl;
+ PUThreadFunc proxy;
+};
+
+struct PUThreadKey_ {
+ DWORD key_idx;
+ PDestroyFunc free_func;
+};
+
+typedef struct PUThreadDestructor_ PUThreadDestructor;
+
+struct PUThreadDestructor_ {
+ DWORD key_idx;
+ PDestroyFunc free_func;
+ PUThreadDestructor *next;
+};
+
+/*
+ * For thread names:
+ * https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
+ */
+
+const DWORD MS_VC_THREAD_NAME_EXCEPTION = 0x406D1388;
+
+#pragma pack(push, 8)
+typedef struct tagTHREADNAME_INFO
+{
+ DWORD dwType; /* Must be 0x1000. */
+ LPCSTR szName; /* Pointer to name (in user addr space). */
+ DWORD dwThreadID; /* Thread ID (-1 = caller thread). */
+ DWORD dwFlags; /* Reserved for future use, must be zero. */
+} THREADNAME_INFO;
+#pragma pack(pop)
+
+#ifndef P_CC_MSVC
+static void *pp_uthread_name_veh_handle = NULL;
+
+static LONG __stdcall
+pp_uthread_set_thread_name_veh (PEXCEPTION_POINTERS except_info)
+{
+ if (except_info->ExceptionRecord != NULL &&
+ except_info->ExceptionRecord->ExceptionCode == MS_VC_THREAD_NAME_EXCEPTION)
+ return EXCEPTION_CONTINUE_EXECUTION;
+
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+/* Rest of definitions */
+
+static PWin32SetThreadDescription pp_uthread_set_descr_func = NULL;
+static PUThreadDestructor * volatile pp_uthread_tls_destructors = NULL;
+static PMutex *pp_uthread_tls_mutex = NULL;
+
+static DWORD pp_uthread_get_tls_key (PUThreadKey *key);
+static puint __stdcall pp_uthread_win32_proxy (ppointer data);
+
+static DWORD
+pp_uthread_get_tls_key (PUThreadKey *key)
+{
+ DWORD tls_key = key->key_idx;
+
+ if (P_LIKELY (tls_key != TLS_OUT_OF_INDEXES))
+ return tls_key;
+
+ p_mutex_lock (pp_uthread_tls_mutex);
+
+ tls_key = key->key_idx;
+
+ if (P_LIKELY (tls_key == TLS_OUT_OF_INDEXES)) {
+ PUThreadDestructor *destr = NULL;
+
+ tls_key = TlsAlloc ();
+
+ if (P_UNLIKELY (tls_key == TLS_OUT_OF_INDEXES)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: TlsAlloc() failed");
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return TLS_OUT_OF_INDEXES;
+ }
+
+ if (key->free_func != NULL) {
+ if (P_UNLIKELY ((destr = p_malloc0 (sizeof (PUThreadDestructor))) == NULL)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: failed to allocate memory");
+
+ if (P_UNLIKELY (TlsFree (tls_key) == 0))
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: TlsFree() failed(1)");
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return TLS_OUT_OF_INDEXES;
+ }
+
+ destr->key_idx = tls_key;
+ destr->free_func = key->free_func;
+ destr->next = pp_uthread_tls_destructors;
+
+ /* At the same time thread exit could be performed at there is no
+ * lock for the global destructor list */
+ if (P_UNLIKELY (p_atomic_pointer_compare_and_exchange ((PVOID volatile *) &pp_uthread_tls_destructors,
+ (PVOID) destr->next,
+ (PVOID) destr) == FALSE)) {
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: p_atomic_pointer_compare_and_exchange() failed");
+
+ if (P_UNLIKELY (TlsFree (tls_key) == 0))
+ P_ERROR ("PUThread::pp_uthread_get_tls_key: TlsFree() failed(2)");
+
+ p_free (destr);
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+ return TLS_OUT_OF_INDEXES;
+ }
+ }
+
+ key->key_idx = tls_key;
+ }
+
+ p_mutex_unlock (pp_uthread_tls_mutex);
+
+ return tls_key;
+}
+
+static puint __stdcall
+pp_uthread_win32_proxy (ppointer data)
+{
+ PUThread *thread = data;
+
+ thread->proxy (thread);
+
+ _endthreadex (0);
+
+ return 0;
+}
+
+void
+p_uthread_win32_thread_detach (void)
+{
+ pboolean was_called;
+
+ do {
+ PUThreadDestructor *destr;
+
+ was_called = FALSE;
+
+ destr = (PUThreadDestructor *) p_atomic_pointer_get ((const PVOID volatile *) &pp_uthread_tls_destructors);
+
+ while (destr != NULL) {
+ ppointer value;
+
+ value = TlsGetValue (destr->key_idx);
+
+ if (value != NULL && destr->free_func != NULL) {
+ TlsSetValue (destr->key_idx, NULL);
+ destr->free_func (value);
+ was_called = TRUE;
+ }
+
+ destr = destr->next;
+ }
+ } while (was_called);
+}
+
+void
+p_uthread_init_internal (void)
+{
+ HMODULE hmodule;
+
+ if (P_LIKELY (pp_uthread_tls_mutex == NULL))
+ pp_uthread_tls_mutex = p_mutex_new ();
+
+ hmodule = GetModuleHandleA ("kernel32.dll");
+
+ if (P_UNLIKELY (hmodule == NULL)) {
+ P_ERROR ("PUThread::p_uthread_init_internal: failed to load kernel32.dll module");
+ return;
+ }
+
+ pp_uthread_set_descr_func = (PWin32SetThreadDescription) GetProcAddress (hmodule, "SetThreadDescription");
+
+#ifndef P_CC_MSVC
+ pp_uthread_name_veh_handle = AddVectoredExceptionHandler (1, &pp_uthread_set_thread_name_veh);
+#endif
+}
+
+void
+p_uthread_shutdown_internal (void)
+{
+ PUThreadDestructor *destr;
+
+ p_uthread_win32_thread_detach ();
+
+ destr = pp_uthread_tls_destructors;
+
+ while (destr != NULL) {
+ PUThreadDestructor *next_destr = destr->next;
+
+ TlsFree (destr->key_idx);
+ p_free (destr);
+
+ destr = next_destr;
+ }
+
+ pp_uthread_tls_destructors = NULL;
+
+ if (P_LIKELY (pp_uthread_tls_mutex != NULL)) {
+ p_mutex_free (pp_uthread_tls_mutex);
+ pp_uthread_tls_mutex = NULL;
+ }
+
+ pp_uthread_set_descr_func = NULL;
+
+#ifndef P_CC_MSVC
+ if (pp_uthread_name_veh_handle != NULL) {
+ RemoveVectoredExceptionHandler (pp_uthread_name_veh_handle);
+ pp_uthread_name_veh_handle = NULL;
+ }
+#endif
+}
+
+PUThread *
+p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size)
+{
+ PUThread *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThread))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->proxy = func;
+
+ if (P_UNLIKELY ((ret->hdl = (HANDLE) _beginthreadex (NULL,
+ (puint) stack_size,
+ pp_uthread_win32_proxy,
+ ret,
+ CREATE_SUSPENDED,
+ NULL)) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: _beginthreadex() failed");
+ p_free (ret);
+ return NULL;
+ }
+
+ ret->base.joinable = joinable;
+
+ p_uthread_set_priority (ret, prio);
+
+ if (P_UNLIKELY (ResumeThread (ret->hdl) == (DWORD) -1)) {
+ P_ERROR ("PUThread::p_uthread_create_internal: ResumeThread() failed");
+ CloseHandle (ret->hdl);
+ p_free (ret);
+ }
+
+ return ret;
+}
+
+void
+p_uthread_exit_internal (void)
+{
+ _endthreadex (0);
+}
+
+void
+p_uthread_wait_internal (PUThread *thread)
+{
+ if (P_UNLIKELY ((WaitForSingleObject (thread->hdl, INFINITE)) != WAIT_OBJECT_0))
+ P_ERROR ("PUThread::p_uthread_wait_internal: WaitForSingleObject() failed");
+}
+
+void
+p_uthread_set_name_internal (PUThread *thread)
+{
+ wchar_t *thr_wname = NULL;
+ psize namelen = 0;
+ HRESULT hres;
+ THREADNAME_INFO thr_info;
+
+ if (pp_uthread_set_descr_func != NULL) {
+ namelen = strlen (thread->base.name);
+
+ if (P_UNLIKELY ((thr_wname = p_malloc0 (sizeof (wchar_t) * (namelen + 1))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_set_name_internal: failed to allocate memory");
+ return;
+ }
+
+ mbstowcs (thr_wname, thread->base.name, namelen + 1);
+
+ hres = pp_uthread_set_descr_func (thread->hdl, thr_wname);
+
+ p_free (thr_wname);
+
+ if (P_UNLIKELY (FAILED (hres))) {
+ P_ERROR ("PUThread::p_uthread_set_name_internal: failed to set thread description");
+ return;
+ }
+ }
+
+ if (!IsDebuggerPresent ())
+ return;
+
+ thr_info.dwType = 0x1000;
+ thr_info.szName = thread->base.name;
+ thr_info.dwThreadID = -1;
+ thr_info.dwFlags = 0;
+
+#ifdef P_CC_MSVC
+# pragma warning(push)
+# pragma warning(disable: 6320 6322)
+ __try {
+ RaiseException (MS_VC_THREAD_NAME_EXCEPTION,
+ 0,
+ sizeof (thr_info) / sizeof (ULONG_PTR),
+ (ULONG_PTR *) &thr_info);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {}
+# pragma warning(pop)
+#else
+ if (pp_uthread_name_veh_handle != NULL)
+ RaiseException (MS_VC_THREAD_NAME_EXCEPTION,
+ 0,
+ sizeof (thr_info) / sizeof (ULONG_PTR),
+ (ULONG_PTR *) &thr_info);
+#endif
+}
+
+void
+p_uthread_free_internal (PUThread *thread)
+{
+ CloseHandle (thread->hdl);
+ p_free (thread);
+}
+
+P_LIB_API void
+p_uthread_yield (void)
+{
+ Sleep (0);
+}
+
+P_LIB_API pboolean
+p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio)
+{
+ pint native_prio;
+
+ if (P_UNLIKELY (thread == NULL))
+ return FALSE;
+
+ switch (prio) {
+ case P_UTHREAD_PRIORITY_IDLE:
+ native_prio = THREAD_PRIORITY_IDLE;
+ break;
+ case P_UTHREAD_PRIORITY_LOWEST:
+ native_prio = THREAD_PRIORITY_LOWEST;
+ break;
+ case P_UTHREAD_PRIORITY_LOW:
+ native_prio = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case P_UTHREAD_PRIORITY_NORMAL:
+ native_prio = THREAD_PRIORITY_NORMAL;
+ break;
+ case P_UTHREAD_PRIORITY_HIGH:
+ native_prio = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case P_UTHREAD_PRIORITY_HIGHEST:
+ native_prio = THREAD_PRIORITY_HIGHEST;
+ break;
+ case P_UTHREAD_PRIORITY_TIMECRITICAL:
+ native_prio = THREAD_PRIORITY_TIME_CRITICAL;
+ break;
+ case P_UTHREAD_PRIORITY_INHERIT:
+ default:
+ native_prio = GetThreadPriority (GetCurrentThread ());
+ break;
+ }
+
+ if (P_UNLIKELY (SetThreadPriority (thread->hdl, native_prio) == 0)) {
+ P_ERROR ("PUThread::p_uthread_set_priority: SetThreadPriority() failed");
+ return FALSE;
+ }
+
+ thread->base.prio = prio;
+
+ return TRUE;
+}
+
+P_LIB_API P_HANDLE
+p_uthread_current_id (void)
+{
+ return (P_HANDLE) ((psize) GetCurrentThreadId ());
+}
+
+P_LIB_API PUThreadKey *
+p_uthread_local_new (PDestroyFunc free_func)
+{
+ PUThreadKey *ret;
+
+ if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PUThreadKey))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_local_new: failed to allocate memory");
+ return NULL;
+ }
+
+ ret->key_idx = TLS_OUT_OF_INDEXES;
+ ret->free_func = free_func;
+
+ return ret;
+}
+
+P_LIB_API void
+p_uthread_local_free (PUThreadKey *key)
+{
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ p_free (key);
+}
+
+P_LIB_API ppointer
+p_uthread_get_local (PUThreadKey *key)
+{
+ DWORD tls_idx;
+
+ if (P_UNLIKELY (key == NULL))
+ return NULL;
+
+ tls_idx = pp_uthread_get_tls_key (key);
+
+ return tls_idx == TLS_OUT_OF_INDEXES ? NULL : TlsGetValue (tls_idx);
+}
+
+P_LIB_API void
+p_uthread_set_local (PUThreadKey *key,
+ ppointer value)
+{
+ DWORD tls_idx;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_idx = pp_uthread_get_tls_key (key);
+
+ if (P_LIKELY (tls_idx != TLS_OUT_OF_INDEXES)) {
+ if (P_UNLIKELY (TlsSetValue (tls_idx, value) == 0))
+ P_ERROR ("PUThread::p_uthread_set_local: TlsSetValue() failed");
+ }
+}
+
+P_LIB_API void
+p_uthread_replace_local (PUThreadKey *key,
+ ppointer value)
+{
+ DWORD tls_idx;
+ ppointer old_value;
+
+ if (P_UNLIKELY (key == NULL))
+ return;
+
+ tls_idx = pp_uthread_get_tls_key (key);
+
+ if (P_UNLIKELY (tls_idx == TLS_OUT_OF_INDEXES))
+ return;
+
+ old_value = TlsGetValue (tls_idx);
+
+ if (old_value != NULL && key->free_func != NULL)
+ key->free_func (old_value);
+
+ if (P_UNLIKELY (TlsSetValue (tls_idx, value) == 0))
+ P_ERROR ("PUThread::p_uthread_replace_local: TlsSetValue() failed");
+}
diff --git a/3rdparty/plibsys/src/puthread.c b/3rdparty/plibsys/src/puthread.c
new file mode 100644
index 0000000..ad72e78
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread.c
@@ -0,0 +1,558 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "patomic.h"
+#ifndef P_OS_WIN
+# include "perror.h"
+#endif
+#include "pmem.h"
+#include "pspinlock.h"
+#include "pstring.h"
+#include "puthread.h"
+#include "puthread-private.h"
+
+#ifdef P_OS_OS2
+# define INCL_DOSPROCESS
+# define INCL_DOSERRORS
+# define INCL_DOSMISC
+# include <os2.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef P_OS_WIN
+# include <unistd.h>
+#endif
+
+#ifdef P_OS_WIN
+typedef void (WINAPI * SystemInfoFunc) (LPSYSTEM_INFO);
+#endif
+
+#ifdef P_OS_HPUX
+# include <sys/pstat.h>
+#endif
+
+#ifdef P_OS_BSD4
+# include <sys/param.h>
+# include <sys/types.h>
+# include <sys/sysctl.h>
+#endif
+
+#ifdef P_OS_VMS
+# define __NEW_STARLET 1
+# include <starlet.h>
+# include <ssdef.h>
+# include <stsdef.h>
+# include <efndef.h>
+# include <iledef.h>
+# include <iosbdef.h>
+# include <syidef.h>
+# include <tis.h>
+# include <lib$routines.h>
+#endif
+
+#ifdef P_OS_QNX6
+# include <sys/syspage.h>
+#endif
+
+#ifdef P_OS_BEOS
+# include <kernel/OS.h>
+#endif
+
+#ifdef P_OS_SYLLABLE
+# include <atheos/sysinfo.h>
+#endif
+
+#if defined (P_OS_SCO) && !defined (_SC_NPROCESSORS_ONLN)
+# include <sys/utsname.h>
+#endif
+
+#ifdef P_OS_AMIGA
+# include <clib/alib_protos.h>
+# include <proto/dos.h>
+# include <proto/exec.h>
+#endif
+
+extern void p_uthread_init_internal (void);
+extern void p_uthread_shutdown_internal (void);
+extern void p_uthread_exit_internal (void);
+extern void p_uthread_wait_internal (PUThread *thread);
+extern void p_uthread_free_internal (PUThread *thread);
+extern void p_uthread_set_name_internal (PUThread *thread);
+extern PUThread * p_uthread_create_internal (PUThreadFunc func,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size);
+
+static void pp_uthread_cleanup (ppointer data);
+static ppointer pp_uthread_proxy (ppointer data);
+
+#ifndef P_OS_WIN
+# if !defined (PLIBSYS_HAS_CLOCKNANOSLEEP) && !defined (PLIBSYS_HAS_NANOSLEEP)
+static pint pp_uthread_nanosleep (puint32 msec);
+# endif
+#endif
+
+static PUThreadKey * pp_uthread_specific_data = NULL;
+static PSpinLock * pp_uthread_new_spin = NULL;
+
+static void
+pp_uthread_cleanup (ppointer data)
+{
+ p_uthread_unref (data);
+}
+
+static ppointer
+pp_uthread_proxy (ppointer data)
+{
+ PUThreadBase *base_thread = data;
+
+ p_uthread_set_local (pp_uthread_specific_data, data);
+
+ p_spinlock_lock (pp_uthread_new_spin);
+ p_spinlock_unlock (pp_uthread_new_spin);
+
+ if (base_thread->name != NULL)
+ p_uthread_set_name_internal ((PUThread *) base_thread);
+
+ base_thread->func (base_thread->data);
+
+ return NULL;
+}
+
+void
+p_uthread_init (void)
+{
+ if (P_LIKELY (pp_uthread_specific_data == NULL))
+ pp_uthread_specific_data = p_uthread_local_new ((PDestroyFunc) pp_uthread_cleanup);
+
+ if (P_LIKELY (pp_uthread_new_spin == NULL))
+ pp_uthread_new_spin = p_spinlock_new ();
+
+ p_uthread_init_internal ();
+}
+
+void
+p_uthread_shutdown (void)
+{
+ PUThread *cur_thread;
+
+ if (P_LIKELY (pp_uthread_specific_data != NULL)) {
+ cur_thread = p_uthread_get_local (pp_uthread_specific_data);
+
+ if (P_UNLIKELY (cur_thread != NULL)) {
+ p_uthread_unref (cur_thread);
+ p_uthread_set_local (pp_uthread_specific_data, NULL);
+ }
+
+ p_uthread_local_free (pp_uthread_specific_data);
+ pp_uthread_specific_data = NULL;
+ }
+
+ if (P_LIKELY (pp_uthread_new_spin != NULL)) {
+ p_spinlock_free (pp_uthread_new_spin);
+ pp_uthread_new_spin = NULL;
+ }
+
+ p_uthread_shutdown_internal ();
+}
+
+P_LIB_API PUThread *
+p_uthread_create_full (PUThreadFunc func,
+ ppointer data,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size,
+ const pchar *name)
+{
+ PUThreadBase *base_thread;
+
+ if (P_UNLIKELY (func == NULL))
+ return NULL;
+
+ p_spinlock_lock (pp_uthread_new_spin);
+
+ base_thread = (PUThreadBase *) p_uthread_create_internal (pp_uthread_proxy,
+ joinable,
+ prio,
+ stack_size);
+
+ if (P_LIKELY (base_thread != NULL)) {
+ base_thread->ref_count = 2;
+ base_thread->ours = TRUE;
+ base_thread->joinable = joinable;
+ base_thread->func = func;
+ base_thread->data = data;
+ base_thread->name = p_strdup (name);
+ }
+
+ p_spinlock_unlock (pp_uthread_new_spin);
+
+ return (PUThread *) base_thread;
+}
+
+P_LIB_API PUThread *
+p_uthread_create (PUThreadFunc func,
+ ppointer data,
+ pboolean joinable,
+ const pchar *name)
+{
+ /* All checks will be inside */
+ return p_uthread_create_full (func, data, joinable, P_UTHREAD_PRIORITY_INHERIT, 0, name);
+}
+
+P_LIB_API void
+p_uthread_exit (pint code)
+{
+ PUThreadBase *base_thread = (PUThreadBase *) p_uthread_current ();
+
+ if (P_UNLIKELY (base_thread == NULL))
+ return;
+
+ if (P_UNLIKELY (base_thread->ours == FALSE)) {
+ P_WARNING ("PUThread::p_uthread_exit: p_uthread_exit() cannot be called from an unknown thread");
+ return;
+ }
+
+ base_thread->ret_code = code;
+
+ p_uthread_exit_internal ();
+}
+
+P_LIB_API pint
+p_uthread_join (PUThread *thread)
+{
+ PUThreadBase *base_thread;
+
+ if (P_UNLIKELY (thread == NULL))
+ return -1;
+
+ base_thread = (PUThreadBase *) thread;
+
+ if (base_thread->joinable == FALSE)
+ return -1;
+
+ p_uthread_wait_internal (thread);
+
+ return base_thread->ret_code;
+}
+
+P_LIB_API PUThread *
+p_uthread_current (void)
+{
+ PUThreadBase *base_thread = p_uthread_get_local (pp_uthread_specific_data);
+
+ if (P_UNLIKELY (base_thread == NULL)) {
+ if (P_UNLIKELY ((base_thread = p_malloc0 (sizeof (PUThreadBase))) == NULL)) {
+ P_ERROR ("PUThread::p_uthread_current: failed to allocate memory");
+ return NULL;
+ }
+
+ base_thread->ref_count = 1;
+
+ p_uthread_set_local (pp_uthread_specific_data, base_thread);
+ }
+
+ return (PUThread *) base_thread;
+}
+
+P_LIB_API pint
+p_uthread_ideal_count (void)
+{
+#if defined (P_OS_WIN)
+ SYSTEM_INFO sys_info;
+ SystemInfoFunc sys_info_func;
+
+ sys_info_func = (SystemInfoFunc) GetProcAddress (GetModuleHandleA ("kernel32.dll"),
+ "GetNativeSystemInfo");
+
+ if (P_UNLIKELY (sys_info_func == NULL))
+ sys_info_func = (SystemInfoFunc) GetProcAddress (GetModuleHandleA ("kernel32.dll"),
+ "GetSystemInfo");
+
+ if (P_UNLIKELY (sys_info_func == NULL)) {
+ P_ERROR ("PUThread::p_uthread_ideal_count: failed to get address of system info procedure");
+ return 1;
+ }
+
+ sys_info_func (&sys_info);
+
+ return (pint) sys_info.dwNumberOfProcessors;
+#elif defined (P_OS_HPUX)
+ struct pst_dynamic psd;
+
+ if (P_LIKELY (pstat_getdynamic (&psd, sizeof (psd), 1, 0) != -1))
+ return (pint) psd.psd_proc_cnt;
+ else {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call pstat_getdynamic()");
+ return 1;
+ }
+#elif defined (P_OS_IRIX)
+ pint cores;
+
+ cores = sysconf (_SC_NPROC_ONLN);
+
+ if (P_UNLIKELY (cores < 0)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call sysconf(_SC_NPROC_ONLN)");
+ cores = 1;
+ }
+
+ return cores;
+#elif defined (P_OS_BSD4)
+ pint cores;
+ pint mib[2];
+ size_t len = sizeof (cores);
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+
+ if (P_UNLIKELY (sysctl (mib, 2, &cores, &len, NULL, 0) == -1)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call sysctl()");
+ return 1;
+ }
+
+ return (pint) cores;
+#elif defined (P_OS_VMS)
+ pint cores;
+ pint status;
+ puint efn;
+ IOSB iosb;
+# if (PLIBSYS_SIZEOF_VOID_P == 4)
+ ILE3 itmlst[] = { { sizeof (cores), SYI$_AVAILCPU_CNT, &cores, NULL},
+ { 0, 0, NULL, NULL}
+ };
+# else
+ ILEB_64 itmlst[] = { { 1, SYI$_AVAILCPU_CNT, -1, sizeof (cores), &cores, NULL},
+ { 0, 0, 0, 0, NULL, NULL}
+ };
+# endif
+
+ status = lib$get_ef (&efn);
+
+ if (P_UNLIKELY (!$VMS_STATUS_SUCCESS (status))) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call lib$get_ef()");
+ return 1;
+ }
+
+ status = sys$getsyi (efn, NULL, NULL, itmlst, &iosb, tis_io_complete, 0);
+
+ if (P_UNLIKELY (!$VMS_STATUS_SUCCESS (status))) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call sys$getsyiw()");
+ lib$free_ef (&efn);
+ return 1;
+ }
+
+ status = tis_synch (efn, &iosb);
+
+ if (P_UNLIKELY (!$VMS_STATUS_SUCCESS (status))) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call tis_synch()");
+ lib$free_ef (&efn);
+ return 1;
+ }
+
+ if (P_UNLIKELY (iosb.iosb$l_getxxi_status != SS$_NORMAL)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: l_getxxi_status is not normal");
+ lib$free_ef (&efn);
+ return 1;
+ }
+
+ lib$free_ef (&efn);
+
+ return cores;
+#elif defined (P_OS_OS2)
+ APIRET ulrc;
+ ULONG cores;
+
+ if (P_UNLIKELY (DosQuerySysInfo (QSV_NUMPROCESSORS,
+ QSV_NUMPROCESSORS,
+ &cores,
+ sizeof (cores)) != NO_ERROR)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call DosQuerySysInfo()");
+ return 1;
+ }
+
+ return (pint) cores;
+#elif defined (P_OS_QNX6)
+ return (pint) _syspage_ptr->num_cpu;
+#elif defined (P_OS_BEOS)
+ system_info sys_info;
+
+ get_system_info (&sys_info);
+
+ return (pint) sys_info.cpu_count;
+#elif defined (P_OS_SYLLABLE)
+ system_info sys_info;
+
+ if (P_UNLIKELY (get_system_info_v (&sys_info, SYS_INFO_VERSION) != 0)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call get_system_info_v()");
+ return 1;
+ }
+
+ return (pint) sys_info.nCPUCount;
+#elif defined (P_OS_AMIGA)
+ puint32 cores;
+
+ IExec->GetCPUInfoTags (GCIT_NumberOfCPUs, &cores, TAG_END);
+
+ return (pint) cores;
+#elif defined (P_OS_SCO) && !defined (_SC_NPROCESSORS_ONLN)
+ struct scoutsname utsn;
+
+ if (P_UNLIKELY (__scoinfo (&utsn, sizeof (utsn)) == -1)) {
+ P_ERROR ("PUThread::p_uthread_ideal_count: failed to call __scoinfo()");
+ return 1;
+ }
+
+ return (pint) utsn.numcpu;
+#elif defined (_SC_NPROCESSORS_ONLN)
+ pint cores;
+
+ cores = (pint) sysconf (_SC_NPROCESSORS_ONLN);
+
+ if (P_UNLIKELY (cores == -1)) {
+ P_WARNING ("PUThread::p_uthread_ideal_count: failed to call sysconf(_SC_NPROCESSORS_ONLN)");
+ return 1;
+ }
+
+ return cores;
+#else
+ return 1;
+#endif
+}
+
+P_LIB_API void
+p_uthread_ref (PUThread *thread)
+{
+ if (P_UNLIKELY (thread == NULL))
+ return;
+
+ p_atomic_int_inc (&((PUThreadBase *) thread)->ref_count);
+}
+
+P_LIB_API void
+p_uthread_unref (PUThread *thread)
+{
+ PUThreadBase *base_thread;
+
+ if (P_UNLIKELY (thread == NULL))
+ return;
+
+ base_thread = (PUThreadBase *) thread;
+
+ if (p_atomic_int_dec_and_test (&base_thread->ref_count) == TRUE) {
+ p_free (base_thread->name);
+
+ if (base_thread->ours == TRUE)
+ p_uthread_free_internal (thread);
+ else
+ p_free (thread);
+ }
+}
+
+#ifndef P_OS_WIN
+# include <errno.h>
+# if !defined (PLIBSYS_HAS_CLOCKNANOSLEEP) && !defined (PLIBSYS_HAS_NANOSLEEP)
+# include <sys/select.h>
+# include <sys/time.h>
+static pint pp_uthread_nanosleep (puint32 msec)
+{
+ pint rc;
+ struct timeval tstart, tstop, tremain, time2wait;
+
+ time2wait.tv_sec = msec / 1000;
+ time2wait.tv_usec = (msec % 1000) * 1000;
+
+ if (P_UNLIKELY (gettimeofday (&tstart, NULL) != 0))
+ return -1;
+
+ rc = -1;
+
+ while (rc != 0) {
+ if (P_UNLIKELY ((rc = select (0, NULL, NULL, NULL, &time2wait)) != 0)) {
+ if (p_error_get_last_system () == EINTR) {
+ if (gettimeofday (&tstop, NULL) != 0)
+ return -1;
+
+ tremain.tv_sec = time2wait.tv_sec -
+ (tstop.tv_sec - tstart.tv_sec);
+ tremain.tv_usec = time2wait.tv_usec -
+ (tstop.tv_usec - tstart.tv_usec);
+ tremain.tv_sec += tremain.tv_usec / 1000000L;
+ tremain.tv_usec %= 1000000L;
+ } else
+ return -1;
+ }
+ }
+
+ return 0;
+}
+# endif
+#endif
+
+P_LIB_API pint
+p_uthread_sleep (puint32 msec)
+{
+#if defined (P_OS_WIN)
+ Sleep (msec);
+ return 0;
+#elif defined (P_OS_OS2)
+ return (DosSleep (msec) == NO_ERROR) ? 0 : -1;
+#elif defined (P_OS_AMIGA)
+ return TimeDelay (0, msec / 1000, (msec % 1000) * 1000) == 0 ? 0 : -1;
+#elif defined (PLIBSYS_HAS_CLOCKNANOSLEEP) || defined (PLIBSYS_HAS_NANOSLEEP)
+ pint result;
+ struct timespec time_req;
+ struct timespec time_rem;
+
+ memset (&time_rem, 0, sizeof (struct timespec));
+
+ time_req.tv_nsec = (msec % 1000) * 1000000L;
+ time_req.tv_sec = (time_t) (msec / 1000);
+
+ result = -1;
+ while (result != 0) {
+ /* Syllable has unimplemented clock_nanocleep() call */
+# if defined (PLIBSYS_HAS_CLOCKNANOSLEEP) && !defined (P_OS_SYLLABLE)
+ if (P_UNLIKELY ((result = clock_nanosleep (CLOCK_MONOTONIC,
+ 0,
+ &time_req,
+ &time_rem)) != 0)) {
+# else
+ if (P_UNLIKELY ((result = nanosleep (&time_req, &time_rem)) != 0)) {
+# endif
+ if (p_error_get_last_system () == EINTR)
+ time_req = time_rem;
+ else
+ return -1;
+ }
+ }
+
+ return 0;
+#else
+ return pp_uthread_nanosleep (msec);
+#endif
+}
diff --git a/3rdparty/plibsys/src/puthread.h b/3rdparty/plibsys/src/puthread.h
new file mode 100644
index 0000000..2c07ac5
--- /dev/null
+++ b/3rdparty/plibsys/src/puthread.h
@@ -0,0 +1,311 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2010-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file puthread.h
+ * @brief Multithreading support
+ * @author Alexander Saprykin
+ *
+ * A thread is a system execution unit which is managed independently by the
+ * scheduler of the operating system. It allows to do things in parallel or
+ * concurrently.
+ *
+ * #PUThread provides a convinient way of multithreading support using native
+ * routines to provide the best performance on the target system.
+ *
+ * To create the thread use the p_uthread_create() or p_uthread_create_full()
+ * routines. Joinable threads allow to wait until their execution is finished
+ * before proceeding further. Thus you can synchronize threads' execution within
+ * the main thread.
+ *
+ * A reference counter mechanism is used to keep track of a #PUThread structure.
+ * It means that the structure will be freed automatically when the reference
+ * counter becomes zero. Use p_uthread_ref() to hold the structure and
+ * p_uthread_unref() to decrement the counter back. A running thread holds a
+ * reference to itself structure, so you do not require to hold a reference
+ * to the thread while it is running.
+ *
+ * Priorities (if supported) allow to tune scheduler behavior: threads with
+ * higher priority will be executed more frequently. Be careful that improper
+ * priorities may lead to negative effects when some threads may receive almost
+ * zero execution time.
+ *
+ * Thread priorities are unreliable: not all operating systems respect thread
+ * priorities in favour of process ones. Priorities may be ignored for bound
+ * threads (every thread bound to a kernel light-weight thread as 1:1), other
+ * systems may require administrative privileges to change the thread priority
+ * (i.e. Linux). Windows always respects thread priorities.
+ *
+ * To put the current thread (even if it was not created using the #PUThread
+ * routines) in a sleep state use p_uthread_sleep().
+ *
+ * You can give a hint to the scheduler that the current thread do not need an
+ * execution time with the p_uthread_yield() routine. This is useful when some
+ * of the threads are in an idle state so you do not want to waste a CPU time.
+ * This only tells to the scheduler to skip the current scheduling cycle for the
+ * calling thread, though the scheduler can ingnore it.
+ *
+ * A thread local storage (TLS) is provided. The TLS key's value can be accessed
+ * through a reference key defined as a #PUThreadKey. A TLS reference key is
+ * some sort of a token which has an associated value. But every thread has its
+ * own token value though using the same token object.
+ *
+ * After creating the TLS reference key every thread can use it to access a
+ * local-specific value. Use the p_uthread_local_new() call to create the TLS
+ * reference key and pass it to every thread which needs local-specific values.
+ * You can also provide a destroy notification function which would be called
+ * upon a TLS key removal which is usually performed on the thread exit.
+ *
+ * There are two calls to set a TLS key's value: p_uthread_set_local() and
+ * p_uthread_replace_local(). The only difference is that the former one calls
+ * the provided destroy notification function before replacing the old value.
+ *
+ * Thread names are used on most of operating systems for debugging purposes,
+ * thereby some limitations for long name can be applied and too long names
+ * will be truncated automatically.
+ */
+
+#if !defined (PLIBSYS_H_INSIDE) && !defined (PLIBSYS_COMPILATION)
+# error "Header files shouldn't be included directly, consider using <plibsys.h> instead."
+#endif
+
+#ifndef PLIBSYS_HEADER_PUTHREAD_H
+#define PLIBSYS_HEADER_PUTHREAD_H
+
+#include <pmacros.h>
+#include <ptypes.h>
+
+P_BEGIN_DECLS
+
+/** Typedef for a #PUThread running method. */
+typedef ppointer (*PUThreadFunc) (ppointer arg);
+
+/** Thread opaque data type. */
+typedef struct PUThread_ PUThread;
+
+/** TLS key opaque data type. */
+typedef struct PUThreadKey_ PUThreadKey;
+
+/** Thread priority. */
+typedef enum PUThreadPriority_ {
+ P_UTHREAD_PRIORITY_INHERIT = 0, /**< Inherits the caller thread priority. Default priority. */
+ P_UTHREAD_PRIORITY_IDLE = 1, /**< Scheduled only when no other threads are running. */
+ P_UTHREAD_PRIORITY_LOWEST = 2, /**< Scheduled less often than #P_UTHREAD_PRIORITY_LOW. */
+ P_UTHREAD_PRIORITY_LOW = 3, /**< Scheduled less often than #P_UTHREAD_PRIORITY_NORMAL. */
+ P_UTHREAD_PRIORITY_NORMAL = 4, /**< Operating system's default priority. */
+ P_UTHREAD_PRIORITY_HIGH = 5, /**< Scheduled more often than #P_UTHREAD_PRIORITY_NORMAL. */
+ P_UTHREAD_PRIORITY_HIGHEST = 6, /**< Scheduled more often than #P_UTHREAD_PRIORITY_HIGH. */
+ P_UTHREAD_PRIORITY_TIMECRITICAL = 7 /**< Scheduled as often as possible. */
+} PUThreadPriority;
+
+/**
+ * @brief Creates a new #PUThread and starts it.
+ * @param func Main thread function to run.
+ * @param data Pointer to pass into the thread main function, may be NULL.
+ * @param joinable Whether to create a joinable thread or not.
+ * @param prio Thread priority.
+ * @param stack_size Thread stack size, in bytes. Leave zero to use a default
+ * value.
+ * @param name Thread name, maybe NULL.
+ * @return Pointer to #PUThread in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note Unreference the returned value after use with p_uthread_unref(). You do
+ * not need to call p_uthread_ref() explicitly on the returned value.
+ */
+P_LIB_API PUThread * p_uthread_create_full (PUThreadFunc func,
+ ppointer data,
+ pboolean joinable,
+ PUThreadPriority prio,
+ psize stack_size,
+ const pchar *name);
+
+/**
+ * @brief Creates a #PUThread and starts it. A short version of
+ * p_uthread_create_full().
+ * @param func Main thread function to run.
+ * @param data Pointer to pass into the thread main function, may be NULL.
+ * @param joinable Whether to create a joinable thread or not.
+ * @param name Thread name, maybe NULL.
+ * @return Pointer to #PUThread in case of success, NULL otherwise.
+ * @since 0.0.1
+ * @note Unreference the returned value after use with p_uthread_unref(). You do
+ * not need to call p_uthread_ref() explicitly on the returned value.
+ */
+P_LIB_API PUThread * p_uthread_create (PUThreadFunc func,
+ ppointer data,
+ pboolean joinable,
+ const pchar *name);
+
+/**
+ * @brief Exits from the currently running (caller) thread.
+ * @param code Exit code.
+ * @since 0.0.1
+ */
+P_LIB_API void p_uthread_exit (pint code);
+
+/**
+ * @brief Waits for the selected thread to become finished.
+ * @param thread Thread to wait for.
+ * @return Thread exit code in case of success, -1 otherwise.
+ * @since 0.0.1
+ * @note Thread must be joinable to return the non-negative result.
+ */
+P_LIB_API pint p_uthread_join (PUThread *thread);
+
+/**
+ * @brief Sleeps the current thread (caller) for a specified amount of time.
+ * @param msec Milliseconds to sleep.
+ * @return 0 in case of success, -1 otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pint p_uthread_sleep (puint32 msec);
+
+/**
+ * @brief Sets a thread priority.
+ * @param thread Thread to set the priority for.
+ * @param prio Priority to set.
+ * @return TRUE in case of success, FALSE otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API pboolean p_uthread_set_priority (PUThread *thread,
+ PUThreadPriority prio);
+
+/**
+ * @brief Tells the scheduler to skip the current (caller) thread in the current
+ * planning stage.
+ * @since 0.0.1
+ *
+ * The scheduler shouldn't give time ticks for the current thread during the
+ * current period, but it may ignore this call.
+ */
+P_LIB_API void p_uthread_yield (void);
+
+/**
+ * @brief Gets an ID of the current (caller) thread.
+ * @return The ID of the current thread.
+ * @since 0.0.1
+ *
+ * This is a platform-dependent type. You shouldn't treat it as a number, it
+ * only gives you the uniquer ID of the thread accross the system.
+ */
+P_LIB_API P_HANDLE p_uthread_current_id (void);
+
+/**
+ * @brief Gets a thread structure of the current (caller) thread.
+ * @return The thread structure of the current thread.
+ * @since 0.0.1
+ * @note This call doesn't not increment the reference counter of the returned
+ * structure.
+ *
+ * A thread structure will be returned even for the thread which was created
+ * outside the library. But you should not use thread manipulation routines over
+ * that structure.
+ */
+P_LIB_API PUThread * p_uthread_current (void);
+
+/**
+ * @brief Gets the ideal number of threads for the system based on the number of
+ * avaialble CPUs and cores (physical and logical).
+ * @return Ideal number of threads, 1 in case of failed detection.
+ * @since 0.0.3
+ */
+P_LIB_API pint p_uthread_ideal_count (void);
+
+/**
+ * @brief Increments a thread reference counter
+ * @param thread #PUThread to increment the reference counter.
+ * @since 0.0.1
+ * @note The #PUThread object will not be removed until the reference counter is
+ * positive.
+ */
+P_LIB_API void p_uthread_ref (PUThread *thread);
+
+/**
+ * @brief Decrements a thread reference counter
+ * @param thread #PUThread to decrement the reference counter.
+ * @since 0.0.1
+ * @note When the reference counter becomes zero the #PUThread is removed from
+ * the memory.
+ */
+P_LIB_API void p_uthread_unref (PUThread *thread);
+
+/**
+ * @brief Create a new TLS reference key.
+ * @param free_func TLS key destroy notification call, leave NULL if not need.
+ * @return New TLS reference key in case of success, NULL otherwise.
+ * @since 0.0.1
+ */
+P_LIB_API PUThreadKey * p_uthread_local_new (PDestroyFunc free_func);
+
+/**
+ * @brief Frees a TLS reference key.
+ * @param key TLS reference key to free.
+ * @since 0.0.1
+ *
+ * It doesn't remove the TLS key itself but only removes a reference used to
+ * access the TLS slot.
+ */
+P_LIB_API void p_uthread_local_free (PUThreadKey *key);
+
+/**
+ * @brief Gets a TLS value.
+ * @param key TLS reference key to get the value for.
+ * @return TLS value for the given key.
+ * @since 0.0.1
+ * @note This call may fail only in case of abnormal use or program behavior,
+ * the NULL value will be returned to tolerance the failure.
+ */
+P_LIB_API ppointer p_uthread_get_local (PUThreadKey *key);
+
+/**
+ * @brief Sets a TLS value.
+ * @param key TLS reference key to set the value for.
+ * @param value TLS value to set.
+ * @since 0.0.1
+ * @note This call may fail only in case of abnormal use or program behavior.
+ *
+ * It doesn't call the destructor notification function provided with
+ * p_uthread_local_new().
+ */
+P_LIB_API void p_uthread_set_local (PUThreadKey *key,
+ ppointer value);
+
+/**
+ * @brief Replaces a TLS value.
+ * @param key TLS reference key to replace the value for.
+ * @param value TLS value to set.
+ * @since 0.0.1
+ * @note This call may fail only in case of abnormal use or program behavior.
+ *
+ * This call does perform the notification function provided with
+ * p_uthread_local_new() on the old TLS value. This is the only difference with
+ * p_uthread_set_local().
+ */
+P_LIB_API void p_uthread_replace_local (PUThreadKey *key,
+ ppointer value);
+
+P_END_DECLS
+
+#endif /* PLIBSYS_HEADER_PUTHREAD_H */
diff --git a/3rdparty/plibsys/tests/CMakeLists.txt b/3rdparty/plibsys/tests/CMakeLists.txt
new file mode 100644
index 0000000..54f747b
--- /dev/null
+++ b/3rdparty/plibsys/tests/CMakeLists.txt
@@ -0,0 +1,96 @@
+# The MIT License
+#
+# Copyright (C) 2018 Alexander Saprykin <saprykin.spb@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# 'Software'), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+project (tests CXX)
+set (OUTPUT_DIR ${CMAKE_BINARY_DIR})
+
+include (${PROJECT_SOURCE_DIR}/../cmake/PlatformDetect.cmake)
+plibsys_detect_target_os (PLIBSYS_TESTS_TARGET_OS)
+
+list (APPEND PLIBSYS_TEST_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/../src ${CMAKE_BINARY_DIR})
+
+if (MSVC)
+ list (APPEND PLIBSYS_TEST_COMPILE_DEFS -D_CRT_SECURE_NO_WARNINGS)
+endif()
+
+macro (plibsys_add_test_executable TEST_NAME SRC_FILE)
+ add_executable (${TEST_NAME} ${SRC_FILE})
+ target_link_libraries (${TEST_NAME} plibsys)
+ set_target_properties (${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
+
+ # QNX requires libm for sqrt() and friends
+ if (PLIBSYS_TESTS_TARGET_OS STREQUAL qnx)
+ target_link_libraries (${TEST_NAME} m)
+ endif()
+
+ # Add include directories
+ if (COMMAND target_include_directories)
+ target_include_directories (${TEST_NAME} PUBLIC ${PLIBSYS_TEST_INCLUDE_DIRS})
+ else()
+ include_directories (${PLIBSYS_TEST_INCLUDE_DIRS})
+ endif()
+
+ # Add compile definitions
+ if (PLIBSYS_TEST_COMPILE_DEFS)
+ if (COMMAND target_compile_definitions)
+ target_compile_definitions (${TEST_NAME} PRIVATE ${PLIBSYS_TEST_COMPILE_DEFS})
+ else()
+ add_definitions (${PLIBSYS_TEST_COMPILE_DEFS})
+ endif()
+ endif()
+
+ if (${TEST_NAME} STREQUAL "plibraryloader_test")
+ add_test (NAME ${TEST_NAME} COMMAND ${TEST_NAME} -- "$<TARGET_FILE:plibsys>")
+ else()
+ add_test (NAME ${TEST_NAME} COMMAND ${TEST_NAME})
+ endif()
+endmacro()
+
+plibsys_add_test_executable (patomic_test patomic_test.cpp)
+plibsys_add_test_executable (pcondvariable_test pcondvariable_test.cpp)
+plibsys_add_test_executable (pcryptohash_test pcryptohash_test.cpp)
+plibsys_add_test_executable (perror_test perror_test.cpp)
+plibsys_add_test_executable (pdir_test pdir_test.cpp)
+plibsys_add_test_executable (pfile_test pfile_test.cpp)
+plibsys_add_test_executable (phashtable_test phashtable_test.cpp)
+plibsys_add_test_executable (pinifile_test pinifile_test.cpp)
+plibsys_add_test_executable (plibraryloader_test plibraryloader_test.cpp)
+plibsys_add_test_executable (plist_test plist_test.cpp)
+plibsys_add_test_executable (pmacros_test pmacros_test.cpp)
+plibsys_add_test_executable (pmain_test pmain_test.cpp)
+plibsys_add_test_executable (pmem_test pmem_test.cpp)
+plibsys_add_test_executable (pmutex_test pmutex_test.cpp)
+plibsys_add_test_executable (pprocess_test pprocess_test.cpp)
+plibsys_add_test_executable (prwlock_test prwlock_test.cpp)
+plibsys_add_test_executable (psemaphore_test psemaphore_test.cpp)
+plibsys_add_test_executable (pshmbuffer_test pshmbuffer_test.cpp)
+plibsys_add_test_executable (pshm_test pshm_test.cpp)
+plibsys_add_test_executable (psocket_test psocket_test.cpp)
+plibsys_add_test_executable (psocketaddress_test psocketaddress_test.cpp)
+plibsys_add_test_executable (pspinlock_test pspinlock_test.cpp)
+plibsys_add_test_executable (pstdarg_test pstdarg_test.cpp)
+plibsys_add_test_executable (pstring_test pstring_test.cpp)
+plibsys_add_test_executable (ptimeprofiler_test ptimeprofiler_test.cpp)
+plibsys_add_test_executable (ptree_test ptree_test.cpp)
+plibsys_add_test_executable (ptypes_test ptypes_test.cpp)
+plibsys_add_test_executable (puthread_test puthread_test.cpp)
diff --git a/3rdparty/plibsys/tests/patomic_test.cpp b/3rdparty/plibsys/tests/patomic_test.cpp
new file mode 100644
index 0000000..6efb2d4
--- /dev/null
+++ b/3rdparty/plibsys/tests/patomic_test.cpp
@@ -0,0 +1,118 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+/* Actually we couldn't test the work of the atomic operations across the
+ * threads, but at least we can test the sanity of operations */
+
+P_TEST_MODULE_INIT ();
+
+P_TEST_CASE_BEGIN (patomic_general_test)
+{
+ p_libsys_init ();
+
+ (void) p_atomic_is_lock_free ();
+
+ pint atomic_int = 0;
+ p_atomic_int_set (&atomic_int, 10);
+
+ P_TEST_CHECK (p_atomic_int_add (&atomic_int, 5) == 10);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 15);
+
+ p_atomic_int_add (&atomic_int, -5);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 10);
+
+ p_atomic_int_inc (&atomic_int);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 11);
+
+ P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == FALSE);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 10);
+
+ P_TEST_CHECK (p_atomic_int_compare_and_exchange (&atomic_int, 10, -10) == TRUE);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -10);
+ P_TEST_CHECK (p_atomic_int_compare_and_exchange (&atomic_int, 10, 20) == FALSE);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -10);
+
+ p_atomic_int_inc (&atomic_int);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -9);
+
+ p_atomic_int_set (&atomic_int, 4);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 4);
+
+ P_TEST_CHECK (p_atomic_int_xor ((puint *) &atomic_int, (puint) 1) == 4);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 5);
+
+ P_TEST_CHECK (p_atomic_int_or ((puint *) &atomic_int, (puint) 2) == 5);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 7);
+
+ P_TEST_CHECK (p_atomic_int_and ((puint *) &atomic_int, (puint) 1) == 7);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 1);
+
+ p_atomic_int_set (&atomic_int, 51);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 51);
+
+ for (pint i = 51; i > 1; --i) {
+ P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == FALSE);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == (i - 1));
+ }
+
+ P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == TRUE);
+ P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 0);
+
+ ppointer atomic_pointer = NULL;
+ p_atomic_pointer_set (&atomic_pointer, PUINT_TO_POINTER (P_MAXSIZE));
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (P_MAXSIZE));
+
+ p_atomic_pointer_set (&atomic_pointer, PUINT_TO_POINTER (100));
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (100));
+ P_TEST_CHECK (p_atomic_pointer_add (&atomic_pointer, (pssize) 100) == 100);
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (200));
+
+ p_atomic_pointer_set (&atomic_pointer, PINT_TO_POINTER (4));
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (4));
+
+ P_TEST_CHECK (p_atomic_pointer_xor (&atomic_pointer, (psize) 1) == 4);
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (5));
+
+ P_TEST_CHECK (p_atomic_pointer_or (&atomic_pointer, (psize) 2) == 5);
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (7));
+
+ P_TEST_CHECK (p_atomic_pointer_and (&atomic_pointer, (psize) 1) == 7);
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (1));
+
+ P_TEST_CHECK (p_atomic_pointer_compare_and_exchange (&atomic_pointer, PUINT_TO_POINTER (1), NULL) == TRUE);
+ P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (patomic_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pcondvariable_test.cpp b/3rdparty/plibsys/tests/pcondvariable_test.cpp
new file mode 100644
index 0000000..887b77f
--- /dev/null
+++ b/3rdparty/plibsys/tests/pcondvariable_test.cpp
@@ -0,0 +1,230 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+#define PCONDTEST_MAX_QUEUE 10
+
+static pint thread_wakeups = 0;
+static pint thread_queue = 0;
+static PCondVariable * queue_empty_cond = NULL;
+static PCondVariable * queue_full_cond = NULL;
+static PMutex * cond_mutex = NULL;
+volatile static pboolean is_working = TRUE;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void * producer_test_thread (void *)
+{
+ while (is_working == TRUE) {
+ if (!p_mutex_lock (cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_broadcast (queue_full_cond);
+ p_uthread_exit (1);
+ }
+
+ while (thread_queue >= PCONDTEST_MAX_QUEUE && is_working == TRUE) {
+ if (!p_cond_variable_wait (queue_empty_cond, cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_broadcast (queue_full_cond);
+ p_mutex_unlock (cond_mutex);
+ p_uthread_exit (1);
+ }
+ }
+
+ if (is_working) {
+ ++thread_queue;
+ ++thread_wakeups;
+ }
+
+ if (!p_cond_variable_broadcast (queue_full_cond)) {
+ is_working = FALSE;
+ p_mutex_unlock (cond_mutex);
+ p_uthread_exit (1);
+ }
+
+ if (!p_mutex_unlock (cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_broadcast (queue_full_cond);
+ p_uthread_exit (1);
+ }
+ }
+
+ p_cond_variable_broadcast (queue_full_cond);
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+static void * consumer_test_thread (void *)
+{
+ while (is_working == TRUE) {
+ if (!p_mutex_lock (cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_signal (queue_empty_cond);
+ p_uthread_exit (1);
+ }
+
+ while (thread_queue <= 0 && is_working == TRUE) {
+ if (!p_cond_variable_wait (queue_full_cond, cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_signal (queue_empty_cond);
+ p_mutex_unlock (cond_mutex);
+ p_uthread_exit (1);
+ }
+ }
+
+ if (is_working) {
+ --thread_queue;
+ ++thread_wakeups;
+ }
+
+ if (!p_cond_variable_signal (queue_empty_cond)) {
+ is_working = FALSE;
+ p_mutex_unlock (cond_mutex);
+ p_uthread_exit (1);
+ }
+
+ if (!p_mutex_unlock (cond_mutex)) {
+ is_working = FALSE;
+ p_cond_variable_signal (queue_empty_cond);
+ p_uthread_exit (1);
+ }
+ }
+
+ p_cond_variable_signal (queue_empty_cond);
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (pcondvariable_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+ P_TEST_CHECK (p_cond_variable_new () == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pcondvariable_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_REQUIRE (p_cond_variable_broadcast (NULL) == FALSE);
+ P_TEST_REQUIRE (p_cond_variable_signal (NULL) == FALSE);
+ P_TEST_REQUIRE (p_cond_variable_wait (NULL, NULL) == FALSE);
+ p_cond_variable_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pcondvariable_general_test)
+{
+ PUThread *thr1, *thr2, *thr3;
+
+ p_libsys_init ();
+
+ queue_empty_cond = p_cond_variable_new ();
+ P_TEST_REQUIRE (queue_empty_cond != NULL);
+ queue_full_cond = p_cond_variable_new ();
+ P_TEST_REQUIRE (queue_full_cond != NULL);
+ cond_mutex = p_mutex_new ();
+ P_TEST_REQUIRE (cond_mutex != NULL);
+
+ is_working = TRUE;
+ thread_wakeups = 0;
+ thread_queue = 0;
+
+ thr1 = p_uthread_create ((PUThreadFunc) producer_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) consumer_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ thr3 = p_uthread_create ((PUThreadFunc) consumer_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr3 != NULL);
+
+ P_TEST_REQUIRE (p_cond_variable_broadcast (queue_empty_cond) == TRUE);
+ P_TEST_REQUIRE (p_cond_variable_broadcast (queue_full_cond) == TRUE);
+
+ p_uthread_sleep (4000);
+
+ is_working = FALSE;
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+ P_TEST_CHECK (p_uthread_join (thr3) == 0);
+
+ P_TEST_REQUIRE (thread_wakeups > 0 && thread_queue >= 0 && thread_queue <= 10);
+
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+ p_uthread_unref (thr3);
+ p_cond_variable_free (queue_empty_cond);
+ p_cond_variable_free (queue_full_cond);
+ p_mutex_free (cond_mutex);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pcondvariable_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pcondvariable_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pcondvariable_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pcryptohash_test.cpp b/3rdparty/plibsys/tests/pcryptohash_test.cpp
new file mode 100644
index 0000000..30c1f91
--- /dev/null
+++ b/3rdparty/plibsys/tests/pcryptohash_test.cpp
@@ -0,0 +1,662 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PCRYPTO_STRESS_LENGTH 10000
+#define PCRYPTO_MAX_UPDATES 1000000
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void
+general_hash_test (PCryptoHashType type,
+ psize hash_len,
+ const pchar *msg1,
+ const pchar *msg2,
+ const puchar *etalon1,
+ const puchar *etalon2,
+ const puchar *etalon3,
+ const pchar *hash1,
+ const pchar *hash2,
+ const pchar *hash3,
+ const pchar *hash_stress)
+{
+ PCryptoHash *crypto_hash;
+ psize dig_len;
+ pchar *hash_str;
+ pchar *long_str;
+ puchar *hash_dig;
+
+ crypto_hash = p_crypto_hash_new (type);
+
+ P_TEST_REQUIRE ((psize) p_crypto_hash_get_length (crypto_hash) == hash_len);
+ P_TEST_REQUIRE (p_crypto_hash_get_type (crypto_hash) == type);
+
+ hash_str = p_crypto_hash_get_string (crypto_hash);
+ P_TEST_REQUIRE (hash_str != NULL);
+ p_crypto_hash_reset (crypto_hash);
+ p_free (hash_str);
+
+ hash_dig = (puchar *) p_malloc0 (hash_len);
+ P_TEST_REQUIRE (hash_dig != NULL);
+
+ long_str = (pchar *) p_malloc0 (PCRYPTO_STRESS_LENGTH);
+ P_TEST_REQUIRE (long_str != NULL);
+
+ for (int i = 0; i < PCRYPTO_STRESS_LENGTH; ++i)
+ long_str[i] = (pchar) (97 + i % 20);
+
+ /* Case 1 */
+
+ /* Check string */
+ p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1));
+ hash_str = p_crypto_hash_get_string (crypto_hash);
+ P_TEST_CHECK (strcmp (hash_str, hash1) == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Check digest */
+ dig_len = hash_len;
+ p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1));
+ p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len);
+
+ P_TEST_CHECK (dig_len == hash_len);
+
+ for (unsigned int i = 0; i < hash_len; ++i)
+ P_TEST_CHECK (hash_dig[i] == etalon1[i]);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Case 2 */
+
+ /* Check string */
+ p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2));
+ hash_str = p_crypto_hash_get_string (crypto_hash);
+ P_TEST_CHECK (strcmp (hash_str, hash2) == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Check digest */
+ dig_len = hash_len;
+ p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2));
+ p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len);
+
+ P_TEST_CHECK (dig_len == hash_len);
+
+ for (unsigned int i = 0; i < hash_len; ++i)
+ P_TEST_CHECK (hash_dig[i] == etalon2[i]);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Case 3 */
+
+ /* Check string */
+ for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i)
+ p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1);
+
+ hash_str = p_crypto_hash_get_string (crypto_hash);
+
+ P_TEST_CHECK (strcmp (hash_str, hash3) == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Check digest */
+ dig_len = hash_len;
+ for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i)
+ p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1);
+
+ p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len);
+ P_TEST_CHECK (dig_len == hash_len);
+
+ for (unsigned int i = 0; i < hash_len; ++i)
+ P_TEST_CHECK (hash_dig[i] == etalon3[i]);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ /* Stress test */
+ p_crypto_hash_update (crypto_hash, (const puchar *) long_str, PCRYPTO_STRESS_LENGTH);
+ hash_str = p_crypto_hash_get_string (crypto_hash);
+
+ P_TEST_CHECK (strcmp (hash_str, hash_stress) == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_reset (crypto_hash);
+
+ p_free (long_str);
+ p_free (hash_dig);
+ p_crypto_hash_free (crypto_hash);
+}
+
+P_TEST_CASE_BEGIN (pcryptohash_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_MD5) == NULL);
+ P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_SHA1) == NULL);
+ P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_GOST) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pcryptohash_invalid_test)
+{
+ PCryptoHash *hash;
+ psize len;
+ pssize md5_len;
+ pchar *hash_str;
+ puchar *buf;
+
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_crypto_hash_new ((PCryptoHashType) -1) == NULL);
+ P_TEST_CHECK (p_crypto_hash_get_length (NULL) == 0);
+ P_TEST_CHECK (p_crypto_hash_get_string (NULL) == NULL);
+ P_TEST_CHECK ((pint) p_crypto_hash_get_type (NULL) == -1);
+ p_crypto_hash_free (NULL);
+
+ p_crypto_hash_update (NULL, NULL, 0);
+ p_crypto_hash_get_digest (NULL, NULL, NULL);
+
+ p_crypto_hash_get_digest (NULL, NULL, &len);
+ P_TEST_CHECK (len == 0);
+
+ p_crypto_hash_reset (NULL);
+
+ hash = p_crypto_hash_new (P_CRYPTO_HASH_TYPE_MD5);
+ P_TEST_CHECK (hash != NULL);
+
+ md5_len = p_crypto_hash_get_length (hash);
+ P_TEST_CHECK (md5_len > 0);
+
+ buf = (puchar *) p_malloc0 (md5_len);
+ P_TEST_CHECK (buf != NULL);
+
+ p_crypto_hash_get_digest (hash, buf, &len);
+ P_TEST_CHECK (len == 0);
+
+ p_crypto_hash_update (hash, (const puchar *) ("abc"), 3);
+ len = ((psize) md5_len) - 1;
+ p_crypto_hash_get_digest (hash, buf, &len);
+ P_TEST_CHECK (len == 0);
+
+ hash_str = p_crypto_hash_get_string (hash);
+ P_TEST_CHECK (strcmp (hash_str, "900150983cd24fb0d6963f7d28e17f72") == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_update (hash, (const puchar *) ("abc"), 3);
+ hash_str = p_crypto_hash_get_string (hash);
+ P_TEST_CHECK (strcmp (hash_str, "900150983cd24fb0d6963f7d28e17f72") == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_free (hash);
+ p_free (buf);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (md5_test)
+{
+ const puchar hash_etalon_1[] = {144, 1, 80, 152, 60, 210, 79, 176,
+ 214, 150, 63, 125, 40, 225, 127, 114};
+ const puchar hash_etalon_2[] = {130, 21, 239, 7, 150, 162, 11, 202,
+ 170, 225, 22, 211, 135, 108, 102, 74};
+ const puchar hash_etalon_3[] = {119, 7, 214, 174, 78, 2, 124, 112,
+ 238, 162, 169, 53, 194, 41, 111, 33};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_MD5,
+ 16,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "900150983cd24fb0d6963f7d28e17f72",
+ "8215ef0796a20bcaaae116d3876c664a",
+ "7707d6ae4e027c70eea2a935c2296f21",
+ "e19ea4a77c97fa6c2521ae1ca66982b9");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha1_test)
+{
+ const puchar hash_etalon_1[] = {169, 153, 62, 54, 71, 6, 129, 106,
+ 186, 62, 37, 113, 120, 80, 194, 108,
+ 156, 208, 216, 157};
+ const puchar hash_etalon_2[] = {132, 152, 62, 68, 28, 59, 210, 110,
+ 186, 174, 74, 161, 249, 81, 41, 229,
+ 229, 70, 112, 241};
+ const puchar hash_etalon_3[] = { 52, 170, 151, 60, 212, 196, 218, 164,
+ 246, 30, 235, 43, 219, 173, 39, 49,
+ 101, 52, 1, 111};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA1,
+ 20,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "a9993e364706816aba3e25717850c26c9cd0d89d",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ "34aa973cd4c4daa4f61eeb2bdbad27316534016f",
+ "56309c2dbe04a348ec801ca5f40b035bad01f907");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha2_224_test)
+{
+ const puchar hash_etalon_1[] = { 35, 9, 125, 34, 52, 5, 216, 34, 134, 66,
+ 164, 119, 189, 162, 85, 179, 42, 173, 188, 228,
+ 189, 160, 179, 247, 227, 108, 157, 167};
+ const puchar hash_etalon_2[] = {117, 56, 139, 22, 81, 39, 118, 204, 93, 186,
+ 93, 161, 253, 137, 1, 80, 176, 198, 69, 92,
+ 180, 245, 139, 25, 82, 82, 37, 37};
+ const puchar hash_etalon_3[] = { 32, 121, 70, 85, 152, 12, 145, 216, 187, 180,
+ 193, 234, 151, 97, 138, 75, 240, 63, 66, 88,
+ 25, 72, 178, 238, 78, 231, 173, 103, };
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_224,
+ 28,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+ "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
+ "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67",
+ "4cf3d45b57e0d54981c4d86954e8378168d5a9f6ceab9e0aae5dd2f6");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha2_256_test)
+{
+ const puchar hash_etalon_1[] = {186, 120, 22, 191, 143, 1, 207, 234,
+ 65, 65, 64, 222, 93, 174, 34, 35,
+ 176, 3, 97, 163, 150, 23, 122, 156,
+ 180, 16, 255, 97, 242, 0, 21, 173};
+ const puchar hash_etalon_2[] = { 36, 141, 106, 97, 210, 6, 56, 184,
+ 229, 192, 38, 147, 12, 62, 96, 57,
+ 163, 60, 228, 89, 100, 255, 33, 103,
+ 246, 236, 237, 212, 25, 219, 6, 193};
+ const puchar hash_etalon_3[] = {205, 199, 110, 92, 153, 20, 251, 146,
+ 129, 161, 199, 226, 132, 215, 62, 103,
+ 241, 128, 154, 72, 164, 151, 32, 14,
+ 4, 109, 57, 204, 199, 17, 44, 208};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_256,
+ 32,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+ "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+ "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
+ "4c2d7749e1b711ca652fda20dd29fe378fd9988f19eadadfa570682e2c55349f");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha2_384_test)
+{
+ const puchar hash_etalon_1[] = {203, 0, 117, 63, 69, 163, 94, 139, 181, 160, 61, 105,
+ 154, 198, 80, 7, 39, 44, 50, 171, 14, 222, 209, 99,
+ 26, 139, 96, 90, 67, 255, 91, 237, 128, 134, 7, 43,
+ 161, 231, 204, 35, 88, 186, 236, 161, 52, 200, 37, 167};
+ const puchar hash_etalon_2[] = { 51, 145, 253, 221, 252, 141, 199, 57, 55, 7, 166, 91,
+ 27, 71, 9, 57, 124, 248, 177, 209, 98, 175, 5, 171,
+ 254, 143, 69, 13, 229, 243, 107, 198, 176, 69, 90, 133,
+ 32, 188, 78, 111, 95, 233, 91, 31, 227, 200, 69, 43};
+ const puchar hash_etalon_3[] = {157, 14, 24, 9, 113, 100, 116, 203, 8, 110, 131, 78,
+ 49, 10, 74, 28, 237, 20, 158, 156, 0, 242, 72, 82,
+ 121, 114, 206, 197, 112, 76, 42, 91, 7, 184, 179, 220,
+ 56, 236, 196, 235, 174, 151, 221, 216, 127, 61, 137, 133};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_384,
+ 48,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+ "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b",
+ "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985",
+ "533e016fd92dd8a8c339328bb5401c3e700e27cd72d8230059e1d4583a506fe8187607bf899a86961af2bf5521b359eb");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha2_512_test)
+{
+ const puchar hash_etalon_1[] = {221, 175, 53, 161, 147, 97, 122, 186,
+ 204, 65, 115, 73, 174, 32, 65, 49,
+ 18, 230, 250, 78, 137, 169, 126, 162,
+ 10, 158, 238, 230, 75, 85, 211, 154,
+ 33, 146, 153, 42, 39, 79, 193, 168,
+ 54, 186, 60, 35, 163, 254, 235, 189,
+ 69, 77, 68, 35, 100, 60, 232, 14,
+ 42, 154, 201, 79, 165, 76, 164, 159};
+ const puchar hash_etalon_2[] = { 32, 74, 143, 198, 221, 168, 47, 10,
+ 12, 237, 123, 235, 142, 8, 164, 22,
+ 87, 193, 110, 244, 104, 178, 40, 168,
+ 39, 155, 227, 49, 167, 3, 195, 53,
+ 150, 253, 21, 193, 59, 27, 7, 249,
+ 170, 29, 59, 234, 87, 120, 156, 160,
+ 49, 173, 133, 199, 167, 29, 215, 3,
+ 84, 236, 99, 18, 56, 202, 52, 69};
+ const puchar hash_etalon_3[] = {231, 24, 72, 61, 12, 231, 105, 100,
+ 78, 46, 66, 199, 188, 21, 180, 99,
+ 142, 31, 152, 177, 59, 32, 68, 40,
+ 86, 50, 168, 3, 175, 169, 115, 235,
+ 222, 15, 242, 68, 135, 126, 166, 10,
+ 76, 176, 67, 44, 229, 119, 195, 27,
+ 235, 0, 156, 92, 44, 73, 170, 46,
+ 78, 173, 178, 23, 173, 140, 192, 155};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_512,
+ 64,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+ "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
+ "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
+ "411525772d02eef0e2ce1107d89b79b8cf6d704e88d4509f726c963d411df6df178c1c9473718f70b0e06c2fda6a9c25f6c91a925849f372634d5f63e6047a20");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha3_224_test)
+{
+ const puchar hash_etalon_1[] = {230, 66, 130, 76, 63, 140, 242, 74, 208, 146,
+ 52, 238, 125, 60, 118, 111, 201, 163, 165, 22,
+ 141, 12, 148, 173, 115, 180, 111, 223};
+ const puchar hash_etalon_2[] = {138, 36, 16, 139, 21, 74, 218, 33, 201, 253,
+ 85, 116, 73, 68, 121, 186, 92, 126, 122, 183,
+ 110, 242, 100, 234, 208, 252, 206, 51};
+ const puchar hash_etalon_3[] = {214, 147, 53, 185, 51, 37, 25, 46, 81, 106,
+ 145, 46, 109, 25, 161, 92, 181, 28, 110, 213,
+ 193, 82, 67, 231, 167, 253, 101, 60};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_224,
+ 28,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf",
+ "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33",
+ "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c",
+ "425fbad801bf675651dcf61af1138831480b562e714c70a2a0050ad3");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha3_256_test)
+{
+ const puchar hash_etalon_1[] = { 58, 152, 93, 167, 79, 226, 37, 178,
+ 4, 92, 23, 45, 107, 211, 144, 189,
+ 133, 95, 8, 110, 62, 157, 82, 91,
+ 70, 191, 226, 69, 17, 67, 21, 50};
+ const puchar hash_etalon_2[] = { 65, 192, 219, 162, 169, 214, 36, 8,
+ 73, 16, 3, 118, 168, 35, 94, 44,
+ 130, 225, 185, 153, 138, 153, 158, 33,
+ 219, 50, 221, 151, 73, 109, 51, 118};
+ const puchar hash_etalon_3[] = { 92, 136, 117, 174, 71, 74, 54, 52,
+ 186, 79, 213, 94, 200, 91, 255, 214,
+ 97, 243, 42, 202, 117, 198, 214, 153,
+ 208, 205, 203, 108, 17, 88, 145, 193};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_256,
+ 32,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532",
+ "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376",
+ "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1",
+ "e37ed9f31da3d61740e04c3124a2da5dbe8be0a2ef5c8b5932d45eb1958219e2");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha3_384_test)
+{
+ const puchar hash_etalon_1[] = {236, 1, 73, 130, 136, 81, 111, 201, 38, 69, 159, 88,
+ 226, 198, 173, 141, 249, 180, 115, 203, 15, 192, 140, 37,
+ 150, 218, 124, 240, 228, 155, 228, 178, 152, 216, 140, 234,
+ 146, 122, 199, 245, 57, 241, 237, 242, 40, 55, 109, 37};
+ const puchar hash_etalon_2[] = {153, 28, 102, 87, 85, 235, 58, 75, 107, 189, 251, 117,
+ 199, 138, 73, 46, 140, 86, 162, 44, 92, 77, 126, 66,
+ 155, 253, 188, 50, 185, 212, 173, 90, 160, 74, 31, 7,
+ 110, 98, 254, 161, 158, 239, 81, 172, 208, 101, 124, 34};
+ const puchar hash_etalon_3[] = {238, 233, 226, 77, 120, 193, 133, 83, 55, 152, 52, 81,
+ 223, 151, 200, 173, 158, 237, 242, 86, 198, 51, 79, 142,
+ 148, 141, 37, 45, 94, 14, 118, 132, 122, 160, 119, 77,
+ 219, 144, 168, 66, 25, 13, 44, 85, 139, 75, 131, 64};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_384,
+ 48,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25",
+ "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22",
+ "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340",
+ "3836508de3aa893ad8bd18df238a79e534bc55a6fae84a557bde0820ccfc3ad58e3eaab29a7d0d3bfc071c6d69b2e9d3");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (sha3_512_test)
+{
+ const puchar hash_etalon_1[] = {183, 81, 133, 11, 26, 87, 22, 138,
+ 86, 147, 205, 146, 75, 107, 9, 110,
+ 8, 246, 33, 130, 116, 68, 247, 13,
+ 136, 79, 93, 2, 64, 210, 113, 46,
+ 16, 225, 22, 233, 25, 42, 243, 201,
+ 26, 126, 197, 118, 71, 227, 147, 64,
+ 87, 52, 11, 76, 244, 8, 213, 165,
+ 101, 146, 248, 39, 78, 236, 83, 240};
+ const puchar hash_etalon_2[] = { 4, 163, 113, 232, 78, 207, 181, 184,
+ 183, 124, 180, 134, 16, 252, 168, 24,
+ 45, 212, 87, 206, 111, 50, 106, 15,
+ 211, 215, 236, 47, 30, 145, 99, 109,
+ 238, 105, 31, 190, 12, 152, 83, 2,
+ 186, 27, 13, 141, 199, 140, 8, 99,
+ 70, 181, 51, 180, 156, 3, 13, 153,
+ 162, 125, 175, 17, 57, 214, 231, 94};
+ const puchar hash_etalon_3[] = { 60, 58, 135, 109, 161, 64, 52, 171,
+ 96, 98, 124, 7, 123, 185, 143, 126,
+ 18, 10, 42, 83, 112, 33, 45, 255,
+ 179, 56, 90, 24, 212, 243, 136, 89,
+ 237, 49, 29, 10, 157, 81, 65, 206,
+ 156, 197, 198, 110, 230, 137, 178, 102,
+ 168, 170, 24, 172, 232, 40, 42, 14,
+ 13, 181, 150, 201, 11, 10, 123, 135};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_512,
+ 64,
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0",
+ "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e",
+ "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87",
+ "16f59fe0b4344af86b37eb145afe41e9dadb45279d074c5bf5c649dd3d2952e47c0ac3a59ea19dc8395d04e8a72fddd9307b839c35fc4bc44a0463003b80dcf1");
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (gost3411_94_test)
+{
+ PCryptoHash *gost3411_94_hash;
+ pchar *hash_str;
+ const puchar hash_etalon_1[] = { 44, 239, 194, 247, 183, 189, 197, 20,
+ 225, 142, 165, 127, 167, 79, 243, 87,
+ 231, 250, 23, 214, 82, 199, 95, 105,
+ 203, 27, 231, 137, 62, 222, 72, 235};
+ const puchar hash_etalon_2[] = {195, 115, 12, 92, 188, 202, 207, 145,
+ 90, 194, 146, 103, 111, 33, 232, 189,
+ 78, 247, 83, 49, 217, 64, 94, 95,
+ 26, 97, 220, 49, 48, 166, 80, 17};
+ const puchar hash_etalon_3[] = {134, 147, 40, 122, 166, 47, 148, 120,
+ 247, 203, 49, 46, 192, 134, 107, 108,
+ 78, 74, 15, 17, 22, 4, 65, 232,
+ 244, 255, 205, 39, 21, 221, 85, 79};
+
+ p_libsys_init ();
+
+ general_hash_test (P_CRYPTO_HASH_TYPE_GOST,
+ 32,
+ "This is message, length=32 bytes",
+ "Suppose the original message has length = 50 bytes",
+ hash_etalon_1,
+ hash_etalon_2,
+ hash_etalon_3,
+ "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb",
+ "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011",
+ "8693287aa62f9478f7cb312ec0866b6c4e4a0f11160441e8f4ffcd2715dd554f",
+ "3738fb45a7f0de6a5447163c0b441ead7a23e48e7af553829dc4300a99f86343");
+
+ gost3411_94_hash = p_crypto_hash_new (P_CRYPTO_HASH_TYPE_GOST);
+
+ P_TEST_REQUIRE (gost3411_94_hash != NULL);
+
+ /* Repeat test */
+ p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14);
+ p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14);
+ p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14);
+ p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14);
+
+ hash_str = p_crypto_hash_get_string (gost3411_94_hash);
+ P_TEST_CHECK (strcmp (hash_str, "9c7b5288c8b3343b29e8ee4a5579593bd90131db7f6fed9b13af4399698b5d29") == 0);
+ p_free (hash_str);
+
+ p_crypto_hash_reset (gost3411_94_hash);
+ p_crypto_hash_free (gost3411_94_hash);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pcryptohash_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pcryptohash_invalid_test);
+ P_TEST_SUITE_RUN_CASE (md5_test);
+ P_TEST_SUITE_RUN_CASE (sha1_test);
+ P_TEST_SUITE_RUN_CASE (sha2_224_test);
+ P_TEST_SUITE_RUN_CASE (sha2_256_test);
+ P_TEST_SUITE_RUN_CASE (sha2_384_test);
+ P_TEST_SUITE_RUN_CASE (sha2_512_test);
+ P_TEST_SUITE_RUN_CASE (sha3_224_test);
+ P_TEST_SUITE_RUN_CASE (sha3_256_test);
+ P_TEST_SUITE_RUN_CASE (sha3_384_test);
+ P_TEST_SUITE_RUN_CASE (sha3_512_test);
+ P_TEST_SUITE_RUN_CASE (gost3411_94_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pdir_test.cpp b/3rdparty/plibsys/tests/pdir_test.cpp
new file mode 100644
index 0000000..7b1689d
--- /dev/null
+++ b/3rdparty/plibsys/tests/pdir_test.cpp
@@ -0,0 +1,248 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PDIR_ENTRY_DIR "test_2"
+#define PDIR_ENTRY_FILE "test_file.txt"
+#define PDIR_TEST_DIR "." P_DIR_SEPARATOR "pdir_test_dir"
+#define PDIR_TEST_DIR_IN "." P_DIR_SEPARATOR "pdir_test_dir" P_DIR_SEPARATOR "test_2"
+#define PDIR_TEST_FILE "." P_DIR_SEPARATOR "pdir_test_dir" P_DIR_SEPARATOR "test_file.txt"
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (pdir_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ /* Cleanup previous run */
+ p_dir_remove (PDIR_TEST_DIR_IN, NULL);
+ p_dir_remove (PDIR_TEST_DIR, NULL);
+
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE);
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE);
+
+ P_TEST_CHECK (p_dir_new (PDIR_TEST_DIR"/", NULL) == NULL);
+
+ /* Revert memory management back */
+ p_mem_restore_vtable ();
+
+ /* Try out of memory when iterating */
+ PDir *dir = p_dir_new (PDIR_TEST_DIR"/", NULL);
+ P_TEST_CHECK (dir != NULL);
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_dir_get_next_entry (dir, NULL) == NULL);
+
+ /* Cleanup */
+ p_mem_restore_vtable ();
+
+ p_dir_free (dir);
+
+ P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR_IN, NULL) == TRUE);
+ P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pdir_general_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_dir_new (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_dir_new ("." P_DIR_SEPARATOR "pdir_test_dir_new", NULL) == NULL);
+ P_TEST_CHECK (p_dir_create (NULL, -1, NULL) == FALSE);
+#ifndef P_OS_VMS
+ P_TEST_CHECK (p_dir_create ("." P_DIR_SEPARATOR "pdir_test_dir_new" P_DIR_SEPARATOR "test_dir", -1, NULL) == FALSE);
+#endif
+ P_TEST_CHECK (p_dir_remove (NULL, NULL) == FALSE);
+ P_TEST_CHECK (p_dir_remove ("." P_DIR_SEPARATOR "pdir_test_dir_new", NULL) == FALSE);
+ P_TEST_CHECK (p_dir_is_exists (NULL) == FALSE);
+ P_TEST_CHECK (p_dir_is_exists ("." P_DIR_SEPARATOR "pdir_test_dir_new") == FALSE);
+ P_TEST_CHECK (p_dir_get_path (NULL) == NULL);
+ P_TEST_CHECK (p_dir_get_next_entry (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_dir_rewind (NULL, NULL) == FALSE);
+
+ p_dir_entry_free (NULL);
+ p_dir_free (NULL);
+
+ /* Cleanup previous run */
+ p_dir_remove (PDIR_TEST_DIR_IN, NULL);
+ p_dir_remove (PDIR_TEST_DIR, NULL);
+
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE);
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE);
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE);
+ P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE);
+
+ FILE *file = fopen (PDIR_TEST_FILE, "w");
+ P_TEST_REQUIRE (file != NULL);
+ P_TEST_REQUIRE (p_file_is_exists (PDIR_TEST_FILE) == TRUE);
+
+ fprintf (file, "This is a test file string\n");
+
+ P_TEST_CHECK (fclose (file) == 0);
+
+ P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR) == TRUE);
+ P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR_IN) == TRUE);
+
+ PDir *dir = p_dir_new (PDIR_TEST_DIR"/", NULL);
+
+ P_TEST_CHECK (dir != NULL);
+
+ pint dir_count = 0;
+ pint file_count = 0;
+ pboolean has_entry_dir = FALSE;
+ pboolean has_entry_file = FALSE;
+
+ PDirEntry *entry;
+
+ while ((entry = p_dir_get_next_entry (dir, NULL)) != NULL) {
+ P_TEST_CHECK (entry->name != NULL);
+
+ switch (entry->type) {
+ case P_DIR_ENTRY_TYPE_DIR:
+ ++dir_count;
+ break;
+ case P_DIR_ENTRY_TYPE_FILE:
+ ++file_count;
+ break;
+ case P_DIR_ENTRY_TYPE_OTHER:
+ default:
+ break;
+ }
+
+ if (strcmp (entry->name, PDIR_ENTRY_DIR) == 0)
+ has_entry_dir = TRUE;
+ else if (strcmp (entry->name, PDIR_ENTRY_FILE) == 0)
+ has_entry_file = TRUE;
+
+ p_dir_entry_free (entry);
+ }
+
+ P_TEST_CHECK (dir_count > 0 && dir_count < 4);
+ P_TEST_CHECK (file_count == 1);
+ P_TEST_CHECK (has_entry_dir == TRUE);
+ P_TEST_CHECK (has_entry_file == TRUE);
+
+ P_TEST_CHECK (p_dir_rewind (dir, NULL) == TRUE);
+
+ pint dir_count_2 = 0;
+ pint file_count_2 = 0;
+ has_entry_dir = FALSE;
+ has_entry_file = FALSE;
+
+ while ((entry = p_dir_get_next_entry (dir, NULL)) != NULL) {
+ P_TEST_CHECK (entry->name != NULL);
+
+ switch (entry->type) {
+ case P_DIR_ENTRY_TYPE_DIR:
+ ++dir_count_2;
+ break;
+ case P_DIR_ENTRY_TYPE_FILE:
+ ++file_count_2;
+ break;
+ case P_DIR_ENTRY_TYPE_OTHER:
+ default:
+ break;
+ }
+
+ if (strcmp (entry->name, PDIR_ENTRY_DIR) == 0)
+ has_entry_dir = TRUE;
+ else if (strcmp (entry->name, PDIR_ENTRY_FILE) == 0)
+ has_entry_file = TRUE;
+
+ p_dir_entry_free (entry);
+ }
+
+ P_TEST_CHECK (dir_count_2 > 0 && dir_count_2 < 4);
+ P_TEST_CHECK (file_count_2 == 1);
+ P_TEST_CHECK (has_entry_dir == TRUE);
+ P_TEST_CHECK (has_entry_file == TRUE);
+
+ /* Compare two previous attempts */
+ P_TEST_CHECK (dir_count == dir_count_2);
+ P_TEST_CHECK (file_count == file_count_2);
+
+ /* Remove all stuff */
+ P_TEST_CHECK (p_file_remove (PDIR_TEST_FILE, NULL) == TRUE);
+ P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == FALSE);
+ P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR_IN, NULL) == TRUE);
+ P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == TRUE);
+
+ P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR_IN) == FALSE);
+ P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR) == FALSE);
+
+ pchar *orig_path = p_dir_get_path (dir);
+ P_TEST_CHECK (strcmp (orig_path, PDIR_TEST_DIR"/") == 0);
+ p_free (orig_path);
+
+ p_dir_free (dir);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pdir_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pdir_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/perror_test.cpp b/3rdparty/plibsys/tests/perror_test.cpp
new file mode 100644
index 0000000..1db2f4d
--- /dev/null
+++ b/3rdparty/plibsys/tests/perror_test.cpp
@@ -0,0 +1,236 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PERROR_TEST_MESSAGE "PError test error message"
+#define PERROR_TEST_MESSAGE_2 "Another PError test error message"
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (perror_nomem_test)
+{
+ p_libsys_init ();
+
+ PError *error = p_error_new_literal (0, 0, NULL);
+ P_TEST_CHECK (error != NULL);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_error_new () == NULL);
+ P_TEST_CHECK (p_error_new_literal (0, 0, NULL) == NULL);
+ P_TEST_CHECK (p_error_copy (error) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_error_free (error);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (perror_invalid_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_error_get_message (NULL) == NULL);
+ P_TEST_CHECK (p_error_get_code (NULL) == 0);
+ P_TEST_CHECK (p_error_get_native_code (NULL) == 0);
+ P_TEST_CHECK (p_error_get_domain (NULL) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (p_error_copy (NULL) == NULL);
+
+ PError *error = (PError *) 0x1;
+
+ p_error_set_code (NULL, 0);
+ p_error_set_native_code (NULL, 0);
+ p_error_set_message (NULL, NULL);
+
+ p_error_set_error (NULL, 0, 0, NULL);
+ p_error_set_error_p (NULL, 0, 0, NULL);
+
+ p_error_set_error_p (&error, 0, 0, NULL);
+ P_TEST_CHECK (error == (PError *) 0x1);
+
+ p_error_clear (NULL);
+ p_error_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (perror_general_test)
+{
+ p_libsys_init ();
+
+ /* Empty initialization test */
+ PError *error = p_error_new ();
+
+ P_TEST_CHECK (error != NULL);
+ P_TEST_CHECK (p_error_get_code (error) == 0);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (p_error_get_message (error) == NULL);
+
+ PError *copy_error = p_error_copy (error);
+
+ P_TEST_CHECK (copy_error != NULL);
+ P_TEST_CHECK (p_error_get_code (copy_error) == 0);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (p_error_get_message (copy_error) == NULL);
+
+ p_error_free (copy_error);
+ copy_error = NULL;
+
+ p_error_set_error (error, (pint) P_ERROR_DOMAIN_IO, -10, PERROR_TEST_MESSAGE);
+
+ P_TEST_CHECK (p_error_get_code (error) == (pint) P_ERROR_DOMAIN_IO);
+ P_TEST_CHECK (p_error_get_native_code (error) == -10);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_IO);
+ P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0);
+
+ /* Change internal data */
+ p_error_set_code (error, (pint) P_ERROR_DOMAIN_IPC);
+ p_error_set_native_code (error, -20);
+ p_error_set_message (error, PERROR_TEST_MESSAGE_2);
+
+ P_TEST_CHECK (p_error_get_code (error) == (pint) P_ERROR_DOMAIN_IPC);
+ P_TEST_CHECK (p_error_get_native_code (error) == -20);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_IPC);
+ P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE_2) == 0);
+
+ /* Revert data back */
+ p_error_set_code (error, 10);
+ p_error_set_native_code (error, -10);
+ p_error_set_message (error, PERROR_TEST_MESSAGE);
+
+ copy_error = p_error_copy (error);
+
+ P_TEST_CHECK (copy_error != NULL);
+ P_TEST_CHECK (p_error_get_code (copy_error) == 10);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (p_error_get_native_code (copy_error) == -10);
+
+ P_TEST_CHECK (strcmp (p_error_get_message (copy_error), PERROR_TEST_MESSAGE) == 0);
+
+ p_error_free (copy_error);
+ copy_error = NULL;
+
+ p_error_set_error (error, 20, -20, PERROR_TEST_MESSAGE_2);
+
+ P_TEST_CHECK (p_error_get_code (error) == 20);
+ P_TEST_CHECK (p_error_get_native_code (error) == -20);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE_2) == 0);
+
+ p_error_clear (error);
+
+ P_TEST_CHECK (p_error_get_code (error) == 0);
+ P_TEST_CHECK (p_error_get_native_code (error) == 0);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (p_error_get_message (error) == NULL);
+
+ p_error_free (error);
+ error = NULL;
+
+ /* Literal initialization test */
+ error = p_error_new_literal (30, -30, PERROR_TEST_MESSAGE);
+
+ P_TEST_CHECK (p_error_get_code (error) == 30);
+ P_TEST_CHECK (p_error_get_native_code (error) == -30);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0);
+
+ copy_error = p_error_copy (error);
+
+ P_TEST_CHECK (copy_error != NULL);
+ P_TEST_CHECK (p_error_get_code (copy_error) == 30);
+ P_TEST_CHECK (p_error_get_native_code (copy_error) == -30);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (strcmp (p_error_get_message (copy_error), PERROR_TEST_MESSAGE) == 0);
+
+ p_error_free (copy_error);
+ p_error_free (error);
+
+ /* Through the double pointer */
+ error = NULL;
+ p_error_set_error_p (&error, 10, -10, PERROR_TEST_MESSAGE);
+
+ P_TEST_CHECK (p_error_get_code (error) == 10);
+ P_TEST_CHECK (p_error_get_native_code (error) == -10);
+ P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE);
+ P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0);
+
+ p_error_free (error);
+
+ /* System codes */
+ p_error_set_last_system (10);
+ P_TEST_CHECK (p_error_get_last_system () == 10);
+ p_error_set_last_system (0);
+ P_TEST_CHECK (p_error_get_last_system () == 0);
+
+#ifndef P_OS_OS2
+ p_error_set_last_net (20);
+ P_TEST_CHECK (p_error_get_last_net () == 20);
+ p_error_set_last_net (0);
+ P_TEST_CHECK (p_error_get_last_net () == 0);
+#endif
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (perror_nomem_test);
+ P_TEST_SUITE_RUN_CASE (perror_invalid_test);
+ P_TEST_SUITE_RUN_CASE (perror_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pfile_test.cpp b/3rdparty/plibsys/tests/pfile_test.cpp
new file mode 100644
index 0000000..7f3c643
--- /dev/null
+++ b/3rdparty/plibsys/tests/pfile_test.cpp
@@ -0,0 +1,61 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdio.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PFILE_TEST_FILE "." P_DIR_SEPARATOR "pfile_test_file.txt"
+
+P_TEST_CASE_BEGIN (pfile_general_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_file_remove (NULL, NULL) == FALSE);
+
+ P_TEST_CHECK (p_file_is_exists (PFILE_TEST_FILE) == FALSE);
+ P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR" pfile_test_file_remove.txt", NULL) == FALSE);
+
+ FILE *file = fopen (PFILE_TEST_FILE, "w");
+ P_TEST_REQUIRE (file != NULL);
+ P_TEST_CHECK (p_file_is_exists (PFILE_TEST_FILE) == TRUE);
+
+ fprintf (file, "This is a test file string\n");
+
+ P_TEST_CHECK (fclose (file) == 0);
+ P_TEST_CHECK (p_file_remove (PFILE_TEST_FILE, NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pfile_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/phashtable_test.cpp b/3rdparty/plibsys/tests/phashtable_test.cpp
new file mode 100644
index 0000000..2975fde
--- /dev/null
+++ b/3rdparty/plibsys/tests/phashtable_test.cpp
@@ -0,0 +1,320 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <time.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PHASHTABLE_STRESS_COUNT 10000
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static int test_hash_table_values (pconstpointer a, pconstpointer b)
+{
+ return a > b ? 0 : (a < b ? -1 : 1);
+}
+
+P_TEST_CASE_BEGIN (phashtable_nomem_test)
+{
+ p_libsys_init ();
+
+ PHashTable *table = p_hash_table_new ();
+ P_TEST_CHECK (table != NULL);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_hash_table_new () == NULL);
+ p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (10));
+ P_TEST_CHECK (p_hash_table_keys (table) == NULL);
+ P_TEST_CHECK (p_hash_table_values (table) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_hash_table_free (table);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (phashtable_invalid_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_hash_table_keys (NULL) == NULL);
+ P_TEST_CHECK (p_hash_table_values (NULL) == NULL);
+ P_TEST_CHECK (p_hash_table_lookup (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_hash_table_lookup_by_value (NULL, NULL, NULL) == NULL);
+ p_hash_table_insert (NULL, NULL, NULL);
+ p_hash_table_remove (NULL, NULL);
+ p_hash_table_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (phashtable_general_test)
+{
+ PHashTable *table = NULL;
+ PList *list = NULL;
+
+ p_libsys_init ();
+
+ table = p_hash_table_new ();
+ P_TEST_REQUIRE (table != NULL);
+
+ /* Test for NULL key */
+ p_hash_table_insert (table, NULL, PINT_TO_POINTER (1));
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 0);
+ p_list_free (list);
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1);
+ p_list_free (list);
+ p_hash_table_remove (table, NULL);
+
+ /* Test for insertion */
+ p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (10));
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 10);
+ p_list_free (list);
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1);
+ p_list_free (list);
+
+ /* False remove */
+ p_hash_table_remove (table, PINT_TO_POINTER (2));
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 10);
+ p_list_free (list);
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1);
+ p_list_free (list);
+
+ /* Replace existing value */
+ p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (15));
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 15);
+ p_list_free (list);
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1);
+ p_list_free (list);
+
+ /* More insertion */
+ p_hash_table_insert (table, PINT_TO_POINTER (2), PINT_TO_POINTER (20));
+ p_hash_table_insert (table, PINT_TO_POINTER (3), PINT_TO_POINTER (30));
+
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 3);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) +
+ PPOINTER_TO_INT (list->next->data) +
+ PPOINTER_TO_INT (list->next->next->data) == 65);
+ p_list_free (list);
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 3);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) +
+ PPOINTER_TO_INT (list->next->data) +
+ PPOINTER_TO_INT (list->next->next->data) == 6);
+ p_list_free (list);
+
+ P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (1))) == 15);
+ P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (2))) == 20);
+ P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (3))) == 30);
+ P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (4)) == (ppointer) -1);
+ p_hash_table_insert (table, PINT_TO_POINTER (22), PINT_TO_POINTER (20));
+
+ list = p_hash_table_lookup_by_value (table,
+ PINT_TO_POINTER (19),
+ (PCompareFunc) test_hash_table_values);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 3);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) +
+ PPOINTER_TO_INT (list->next->data) +
+ PPOINTER_TO_INT (list->next->next->data) == 27);
+ p_list_free (list);
+
+ list = p_hash_table_lookup_by_value (table,
+ PINT_TO_POINTER (20),
+ NULL);
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_REQUIRE (p_list_length (list) == 2);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) +
+ PPOINTER_TO_INT (list->next->data) == 24);
+ p_list_free (list);
+
+ P_TEST_REQUIRE (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (22))) == 20);
+
+ p_hash_table_remove (table, PINT_TO_POINTER (1));
+ p_hash_table_remove (table, PINT_TO_POINTER (2));
+
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (p_list_length (list) == 2);
+ p_list_free (list);
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (p_list_length (list) == 2);
+ p_list_free (list);
+
+ p_hash_table_remove (table, PINT_TO_POINTER (3));
+
+ list = p_hash_table_keys (table);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 22);
+ p_list_free (list);
+ list = p_hash_table_values (table);
+ P_TEST_REQUIRE (p_list_length (list) == 1);
+ P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 20);
+ p_list_free (list);
+
+ p_hash_table_remove (table, PINT_TO_POINTER (22));
+
+ P_TEST_REQUIRE (p_hash_table_keys (table) == NULL);
+ P_TEST_REQUIRE (p_hash_table_values (table) == NULL);
+
+ p_hash_table_free (table);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (phashtable_stress_test)
+{
+ p_libsys_init ();
+
+ PHashTable *table = p_hash_table_new ();
+ P_TEST_REQUIRE (table != NULL);
+
+ srand ((unsigned int) time (NULL));
+
+ int counter = 0;
+
+ pint *keys = (pint *) p_malloc0 (PHASHTABLE_STRESS_COUNT * sizeof (pint));
+ pint *values = (pint *) p_malloc0 (PHASHTABLE_STRESS_COUNT * sizeof (pint));
+
+ P_TEST_REQUIRE (keys != NULL);
+ P_TEST_REQUIRE (values != NULL);
+
+ while (counter != PHASHTABLE_STRESS_COUNT) {
+ pint rand_number = rand ();
+
+ if (p_hash_table_lookup (table, PINT_TO_POINTER (rand_number)) != (ppointer) (-1))
+ continue;
+
+ keys[counter] = rand_number;
+ values[counter] = rand () + 1;
+
+ p_hash_table_remove (table, PINT_TO_POINTER (keys[counter]));
+ p_hash_table_insert (table, PINT_TO_POINTER (keys[counter]), PINT_TO_POINTER (values[counter]));
+
+ ++counter;
+ }
+
+ for (int i = 0; i < PHASHTABLE_STRESS_COUNT; ++i) {
+ P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (keys[i])) ==
+ PINT_TO_POINTER (values[i]));
+
+ p_hash_table_remove (table, PINT_TO_POINTER (keys[i]));
+ P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (keys[i])) == (ppointer) (-1));
+ }
+
+ P_TEST_CHECK (p_hash_table_keys (table) == NULL);
+ P_TEST_CHECK (p_hash_table_values (table) == NULL);
+
+ p_free (keys);
+ p_free (values);
+
+ p_hash_table_free (table);
+
+ /* Try to free at once */
+ table = p_hash_table_new ();
+ P_TEST_REQUIRE (table != NULL);
+
+ counter = 0;
+
+ while (counter != PHASHTABLE_STRESS_COUNT) {
+ pint rand_number = rand ();
+
+ if (p_hash_table_lookup (table, PINT_TO_POINTER (rand_number)) != (ppointer) (-1))
+ continue;
+
+ p_hash_table_insert (table, PINT_TO_POINTER (rand_number), PINT_TO_POINTER (rand () + 1));
+
+ ++counter;
+ }
+
+ p_hash_table_free (table);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (phashtable_nomem_test);
+ P_TEST_SUITE_RUN_CASE (phashtable_invalid_test);
+ P_TEST_SUITE_RUN_CASE (phashtable_general_test);
+ P_TEST_SUITE_RUN_CASE (phashtable_stress_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pinifile_test.cpp b/3rdparty/plibsys/tests/pinifile_test.cpp
new file mode 100644
index 0000000..3d4d4c8
--- /dev/null
+++ b/3rdparty/plibsys/tests/pinifile_test.cpp
@@ -0,0 +1,357 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PINIFILE_STRESS_LINE 2048
+#define PINIFILE_MAX_LINE 1024
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static bool create_test_ini_file (bool last_empty_section)
+{
+ FILE *file = fopen ("." P_DIR_SEPARATOR "p_ini_test_file.ini", "w");
+
+ if (file == NULL)
+ return false;
+
+ pchar *buf = (pchar *) p_malloc0 (PINIFILE_STRESS_LINE + 1);
+
+ for (int i = 0; i < PINIFILE_STRESS_LINE; ++i)
+ buf[i] = (pchar) (97 + i % 20);
+
+ /* Empty section */
+ fprintf (file, "[empty_section]\n");
+
+ /* Numeric section */
+ fprintf (file, "[numeric_section]\n");
+ fprintf (file, "int_parameter_1 = 4\n");
+ fprintf (file, "int_parameter_2 = 5 ;This is a comment\n");
+ fprintf (file, "int_parameter_3 = 6 #This is another type of a comment\n");
+ fprintf (file, "# Whole line is a comment\n");
+ fprintf (file, "; Yet another comment line\n");
+ fprintf (file, "float_parameter_1 = 3.24\n");
+ fprintf (file, "float_parameter_2 = 0.15\n");
+
+ /* String section */
+ fprintf (file, "[string_section]\n");
+ fprintf (file, "string_parameter_1 = Test string\n");
+ fprintf (file, "string_parameter_2 = \"Test string with #'\"\n");
+ fprintf (file, "string_parameter_3 = \n");
+ fprintf (file, "string_parameter_4 = 12345 ;Comment\n");
+ fprintf (file, "string_parameter_4 = 54321\n");
+ fprintf (file, "string_parameter_5 = 'Test string'\n");
+ fprintf (file, "string_parameter_6 = %s\n", buf);
+ fprintf (file, "string_parameter_7 = ''\n");
+ fprintf (file, "string_parameter_8 = \"\"\n");
+ fprintf (file, "%s = stress line\n", buf);
+
+ /* Boolean section */
+ fprintf (file, "[boolean_section]\n");
+ fprintf (file, "boolean_parameter_1 = TRUE ;True value\n");
+ fprintf (file, "boolean_parameter_2 = 0 ;False value\n");
+ fprintf (file, "boolean_parameter_3 = false ;False value\n");
+ fprintf (file, "boolean_parameter_4 = 1 ;True value\n");
+
+ /* List section */
+ fprintf (file, "[list_section]\n");
+ fprintf (file, "list_parameter_1 = {1\t2\t5\t10} ;First list\n");
+ fprintf (file, "list_parameter_2 = {2.0 3.0 5.0} #Second list\n");
+ fprintf (file, "list_parameter_3 = {true FALSE 1} #Last list\n");
+
+ /* Empty section */
+ if (last_empty_section)
+ fprintf (file, "[empty_section_2]\n");
+
+ p_free (buf);
+
+ return fclose (file) == 0;
+}
+
+P_TEST_CASE_BEGIN (pinifile_nomem_test)
+{
+ p_libsys_init ();
+
+ P_TEST_REQUIRE (create_test_ini_file (false));
+
+ PIniFile *ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini");
+ P_TEST_CHECK (ini != NULL);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini") == NULL);
+ P_TEST_CHECK (p_ini_file_parse (ini, NULL) == TRUE);
+ P_TEST_CHECK (p_ini_file_sections (ini) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_ini_file_free (ini);
+
+ ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini");
+ P_TEST_CHECK (ini != NULL);
+
+ P_TEST_CHECK (p_ini_file_parse (ini, NULL) == TRUE);
+ PList *section_list = p_ini_file_sections (ini);
+ P_TEST_CHECK (section_list != NULL);
+ P_TEST_CHECK (p_list_length (section_list) == 4);
+
+ p_list_foreach (section_list, (PFunc) p_free, NULL);
+ p_list_free (section_list);
+ p_ini_file_free (ini);
+
+ P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_ini_test_file.ini", NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pinifile_bad_input_test)
+{
+ PIniFile *ini = NULL;
+
+ p_libsys_init ();
+
+ p_ini_file_free (ini);
+ P_TEST_CHECK (p_ini_file_new (NULL) == NULL);
+ P_TEST_CHECK (p_ini_file_parse (ini, NULL) == FALSE);
+ P_TEST_CHECK (p_ini_file_is_parsed (ini) == FALSE);
+ P_TEST_CHECK (p_ini_file_is_key_exists (ini, "string_section", "string_paramter_1") == FALSE);
+ P_TEST_CHECK (p_ini_file_sections (ini) == NULL);
+ P_TEST_CHECK (p_ini_file_keys (ini, "string_section") == NULL);
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_1", FALSE) == FALSE);
+ P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_1", 1.0), 1.0, 0.0001);
+ P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_1", 0) == 0);
+ P_TEST_CHECK (p_ini_file_parameter_list (ini, "list_section", "list_parameter_1") == NULL);
+ P_TEST_CHECK (p_ini_file_parameter_string (ini, "string_section", "string_parameter_1", NULL) == NULL);
+
+ ini = p_ini_file_new ("./bad_file_path/fake.ini");
+ P_TEST_CHECK (ini != NULL);
+ P_TEST_CHECK (p_ini_file_parse (ini, NULL) == FALSE);
+ p_ini_file_free (ini);
+
+ P_TEST_REQUIRE (create_test_ini_file (true));
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pinifile_read_test)
+{
+ p_libsys_init ();
+
+ PIniFile *ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini");
+ P_TEST_REQUIRE (ini != NULL);
+ P_TEST_CHECK (p_ini_file_is_parsed (ini) == FALSE);
+
+ P_TEST_REQUIRE (p_ini_file_parse (ini, NULL) == TRUE);
+ P_TEST_CHECK (p_ini_file_is_parsed (ini) == TRUE);
+ P_TEST_REQUIRE (p_ini_file_parse (ini, NULL) == TRUE);
+ P_TEST_CHECK (p_ini_file_is_parsed (ini) == TRUE);
+
+ /* Test list of sections */
+ PList *list = p_ini_file_sections (ini);
+ P_TEST_CHECK (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 4);
+
+ p_list_foreach (list, (PFunc) p_free, NULL);
+ p_list_free (list);
+
+ /* Test empty section */
+ list = p_ini_file_keys (ini, "empty_section");
+ P_TEST_CHECK (list == NULL);
+
+ /* Test numeric section */
+ list = p_ini_file_keys (ini, "numeric_section");
+ P_TEST_CHECK (p_list_length (list) == 5);
+ p_list_foreach (list, (PFunc) p_free, NULL);
+ p_list_free (list);
+
+ P_TEST_CHECK (p_ini_file_parameter_list (ini, "numeric_section", "int_parameter_1") == NULL);
+ P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_1", -1) == 4);
+ P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_2", -1) == 5);
+ P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_3", -1) == 6);
+ P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_def", 10) == 10);
+ P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_1", -1.0), 3.24, 0.0001);
+ P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_2", -1.0), 0.15, 0.0001);
+ P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section_no", "float_parameter_def", 10.0), 10.0, 0.0001);
+ P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section", "int_parameter_1") == TRUE);
+ P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section", "float_parameter_1") == TRUE);
+ P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section_false", "float_parameter_1") == FALSE);
+
+ /* Test string section */
+ list = p_ini_file_keys (ini, "string_section");
+ P_TEST_CHECK (p_list_length (list) == 8);
+ p_list_foreach (list, (PFunc) p_free, NULL);
+ p_list_free (list);
+
+ pchar *str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_1", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "Test string") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_2", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "Test string with #'") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_3", NULL);
+ P_TEST_REQUIRE (str == NULL);
+ P_TEST_CHECK (p_ini_file_is_key_exists (ini, "string_section", "string_parameter_3") == FALSE);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_4", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "54321") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_5", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "Test string") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_6", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strlen (str) > 0 && strlen (str) < PINIFILE_MAX_LINE);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_7", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_8", NULL);
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "") == 0);
+ p_free (str);
+
+ str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_def", "default_value");
+ P_TEST_REQUIRE (str != NULL);
+ P_TEST_CHECK (strcmp (str, "default_value") == 0);
+ p_free (str);
+
+ /* Test boolean section */
+ list = p_ini_file_keys (ini, "boolean_section");
+ P_TEST_CHECK (p_list_length (list) == 4);
+ p_list_foreach (list, (PFunc) p_free, NULL);
+ p_list_free (list);
+
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_1", FALSE) == TRUE);
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_2", TRUE) == FALSE);
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_3", TRUE) == FALSE);
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_4", FALSE) == TRUE);
+ P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_section_def", TRUE) == TRUE);
+
+ /* Test list section */
+ list = p_ini_file_keys (ini, "list_section");
+ P_TEST_CHECK (p_list_length (list) == 3);
+ p_list_foreach (list, (PFunc) p_free, NULL);
+ p_list_free (list);
+
+ /* -- First list parameter */
+ PList *list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_1");
+ P_TEST_CHECK (list_val != NULL);
+ P_TEST_CHECK (p_list_length (list_val) == 4);
+
+ pint int_sum = 0;
+ for (PList *iter = list_val; iter != NULL; iter = iter->next)
+ int_sum += atoi ((const pchar *) (iter->data));
+
+ P_TEST_CHECK (int_sum == 18);
+ p_list_foreach (list_val, (PFunc) p_free, NULL);
+ p_list_free (list_val);
+
+ /* -- Second list parameter */
+ list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_2");
+ P_TEST_CHECK (list_val != NULL);
+ P_TEST_CHECK (p_list_length (list_val) == 3);
+
+ double flt_sum = 0;
+ for (PList *iter = list_val; iter != NULL; iter = iter->next)
+ flt_sum += atof ((const pchar *) (iter->data));
+
+ P_TEST_CHECK_CLOSE (flt_sum, 10.0, 0.0001);
+ p_list_foreach (list_val, (PFunc) p_free, NULL);
+ p_list_free (list_val);
+
+ /* -- Third list parameter */
+ list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_3");
+ P_TEST_CHECK (list_val != NULL);
+ P_TEST_CHECK (p_list_length (list_val) == 3);
+
+ pboolean bool_sum = TRUE;
+ for (PList *iter = list_val; iter != NULL; iter = iter->next)
+ bool_sum = bool_sum && atoi ((const pchar *) (iter->data));
+
+ P_TEST_CHECK (bool_sum == FALSE);
+ p_list_foreach (list_val, (PFunc) p_free, NULL);
+ p_list_free (list_val);
+
+ /* -- False list parameter */
+ P_TEST_CHECK (p_ini_file_parameter_list (ini, "list_section_no", "list_parameter_def") == NULL);
+
+ p_ini_file_free (ini);
+
+ P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_ini_test_file.ini", NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pinifile_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pinifile_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pinifile_read_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/plibraryloader_test.cpp b/3rdparty/plibsys/tests/plibraryloader_test.cpp
new file mode 100644
index 0000000..52ce1b0
--- /dev/null
+++ b/3rdparty/plibsys/tests/plibraryloader_test.cpp
@@ -0,0 +1,179 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdio.h>
+
+P_TEST_MODULE_INIT ();
+
+static int g_argc = 0;
+static char **g_argv = NULL;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (plibraryloader_nomem_test)
+{
+ p_libsys_init ();
+
+ if (P_UNLIKELY (p_library_loader_is_ref_counted () == FALSE)) {
+ p_libsys_shutdown ();
+ P_TEST_CASE_RETURN ();
+ }
+
+ /* We assume that 3rd argument is ourself library path */
+ P_TEST_REQUIRE (g_argc > 1);
+
+ /* Cleanup from previous run */
+ p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL);
+
+ FILE *file = fopen ("." P_DIR_SEPARATOR "p_empty_file.txt", "w");
+ P_TEST_CHECK (file != NULL);
+ P_TEST_CHECK (fclose (file) == 0);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+#ifdef P_OS_WIN
+ SetErrorMode (SEM_FAILCRITICALERRORS);
+#endif
+
+ P_TEST_CHECK (p_library_loader_new ("." P_DIR_SEPARATOR "p_empty_file.txt") == NULL);
+ P_TEST_CHECK (p_library_loader_new (g_argv[g_argc - 1]) == NULL);
+
+#ifdef P_OS_WIN
+ SetErrorMode (0);
+#endif
+
+ p_mem_restore_vtable ();
+
+ P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (plibraryloader_general_test)
+{
+ PLibraryLoader *loader;
+ pchar *err_msg;
+ void (*shutdown_func) (void);
+
+ p_libsys_init ();
+
+ /* We assume that 3rd argument is ourself library path */
+ P_TEST_REQUIRE (g_argc > 1);
+
+ /* Invalid usage */
+ P_TEST_CHECK (p_library_loader_new (NULL) == NULL);
+ P_TEST_CHECK (p_library_loader_new ("./unexistent_file.nofile") == NULL);
+ P_TEST_CHECK (p_library_loader_get_symbol (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_library_loader_get_symbol (NULL, "unexistent_symbol") == NULL);
+
+ p_library_loader_free (NULL);
+
+ /* General tests */
+
+ /* At least not on HP-UX it should be true */
+#if !defined (P_OS_HPUX)
+ P_TEST_CHECK (p_library_loader_is_ref_counted () == TRUE);
+#else
+ p_library_loader_is_ref_counted ();
+#endif
+
+ err_msg = p_library_loader_get_last_error (NULL);
+ p_free (err_msg);
+
+ if (P_UNLIKELY (p_library_loader_is_ref_counted () == FALSE)) {
+ p_libsys_shutdown ();
+ P_TEST_CASE_RETURN ();
+ }
+
+ loader = p_library_loader_new (g_argv[g_argc - 1]);
+ P_TEST_REQUIRE (loader != NULL);
+
+ P_TEST_CHECK (p_library_loader_get_symbol (loader, "there_is_no_such_a_symbol") == (PFuncAddr) NULL);
+
+ err_msg = p_library_loader_get_last_error (loader);
+ P_TEST_CHECK (err_msg != NULL);
+ p_free (err_msg);
+
+ shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown");
+
+ if (shutdown_func == NULL)
+ shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "_p_libsys_shutdown");
+
+ /* For Watcom C */
+
+ if (shutdown_func == NULL)
+ shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown_");
+
+ P_TEST_REQUIRE (shutdown_func != NULL);
+
+ err_msg = p_library_loader_get_last_error (loader);
+ p_free (err_msg);
+
+ p_library_loader_free (loader);
+
+#ifdef P_OS_BEOS
+ p_libsys_shutdown ();
+#else
+ /* We have already loaded reference to ourself library, it's OK */
+ shutdown_func ();
+#endif
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_ARGS_BEGIN()
+{
+ g_argc = argc;
+ g_argv = argv;
+
+ P_TEST_SUITE_RUN_CASE (plibraryloader_nomem_test);
+ P_TEST_SUITE_RUN_CASE (plibraryloader_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/plist_test.cpp b/3rdparty/plibsys/tests/plist_test.cpp
new file mode 100644
index 0000000..87933ae
--- /dev/null
+++ b/3rdparty/plibsys/tests/plist_test.cpp
@@ -0,0 +1,200 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+typedef struct _TestData {
+ pint test_array[3];
+ pint index;
+} TestData;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void foreach_test_func (ppointer data, ppointer user_data)
+{
+ if (user_data == NULL)
+ return;
+
+ TestData *test_data = (TestData *) user_data;
+
+ if (test_data->index < 0 || test_data->index > 2)
+ return;
+
+ test_data->test_array[test_data->index] = P_POINTER_TO_INT (data);
+ ++test_data->index;
+}
+
+P_TEST_CASE_BEGIN (plist_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_list_append (NULL, PINT_TO_POINTER (10)) == NULL);
+ P_TEST_CHECK (p_list_prepend (NULL, PINT_TO_POINTER (10)) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (plist_invalid_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_list_remove (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_list_last (NULL) == NULL);
+ P_TEST_CHECK (p_list_length (NULL) == 0);
+ P_TEST_CHECK (p_list_reverse (NULL) == NULL);
+
+ p_list_free (NULL);
+ p_list_foreach (NULL, NULL, NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (plist_general_test)
+{
+ PList *list = NULL;
+ TestData test_data;
+
+ p_libsys_init ();
+
+ /* Testing append */
+ list = p_list_append (list, P_INT_TO_POINTER (32));
+ list = p_list_append (list, P_INT_TO_POINTER (64));
+
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 2);
+
+ /* Testing data access */
+ P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 32);
+ P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 64);
+
+ /* Testing prepend */
+ list = p_list_prepend (list, P_INT_TO_POINTER (128));
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 3);
+ P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 128);
+ P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 64);
+
+ /* Testing for each loop */
+ memset (&test_data, 0, sizeof (test_data));
+
+ P_TEST_REQUIRE (test_data.test_array[0] == 0);
+ P_TEST_REQUIRE (test_data.test_array[1] == 0);
+ P_TEST_REQUIRE (test_data.test_array[2] == 0);
+ P_TEST_REQUIRE (test_data.index == 0);
+
+ p_list_foreach (list, (PFunc) foreach_test_func, (ppointer) &test_data);
+
+ P_TEST_CHECK (test_data.index == 3);
+ P_TEST_CHECK (test_data.test_array[0] == 128);
+ P_TEST_CHECK (test_data.test_array[1] == 32);
+ P_TEST_CHECK (test_data.test_array[2] == 64);
+
+ /* Testing reverse */
+
+ list = p_list_reverse (list);
+
+ P_TEST_CHECK (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 3);
+ P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 64);
+ P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 128);
+
+ /* Testing for each loop */
+ memset (&test_data, 0, sizeof (test_data));
+
+ P_TEST_REQUIRE (test_data.test_array[0] == 0);
+ P_TEST_REQUIRE (test_data.test_array[1] == 0);
+ P_TEST_REQUIRE (test_data.test_array[2] == 0);
+ P_TEST_REQUIRE (test_data.index == 0);
+
+ p_list_foreach (list, (PFunc) foreach_test_func, (ppointer) &test_data);
+
+ P_TEST_CHECK (test_data.index == 3);
+ P_TEST_CHECK (test_data.test_array[0] == 64);
+ P_TEST_CHECK (test_data.test_array[1] == 32);
+ P_TEST_CHECK (test_data.test_array[2] == 128);
+
+ /* Testing remove */
+ list = p_list_remove (list, P_INT_TO_POINTER (32));
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 2);
+
+ list = p_list_remove (list, P_INT_TO_POINTER (128));
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 1);
+
+ list = p_list_remove (list, P_INT_TO_POINTER (256));
+ P_TEST_REQUIRE (list != NULL);
+ P_TEST_CHECK (p_list_length (list) == 1);
+
+ list = p_list_remove (list, P_INT_TO_POINTER (64));
+ P_TEST_REQUIRE (list == NULL);
+ P_TEST_CHECK (p_list_length (list) == 0);
+
+ p_list_free (list);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (plist_nomem_test);
+ P_TEST_SUITE_RUN_CASE (plist_invalid_test);
+ P_TEST_SUITE_RUN_CASE (plist_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pmacros_test.cpp b/3rdparty/plibsys/tests/pmacros_test.cpp
new file mode 100644
index 0000000..fed35a2
--- /dev/null
+++ b/3rdparty/plibsys/tests/pmacros_test.cpp
@@ -0,0 +1,646 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2014-2018 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <time.h>
+
+P_TEST_MODULE_INIT ();
+
+static P_GNUC_WARN_UNUSED_RESULT pint unused_result_test_func ()
+{
+ return 0;
+}
+
+P_LIB_INTERNAL_API int internal_api_test ()
+{
+ return 0;
+}
+
+P_LIB_GLOBAL_API int global_api_test ()
+{
+ return 0;
+}
+
+P_TEST_CASE_BEGIN (pmacros_general_test)
+{
+ p_libsys_init ();
+
+ /* Test OS detection macros */
+#if !defined (P_OS_DARWIN) && !defined (P_OS_MAC9) && !defined (P_OS_BSD4) && \
+ !defined (P_OS_AIX) && !defined (P_OS_HPUX) && !defined (P_OS_SOLARIS) && \
+ !defined (P_OS_QNX) && !defined (P_OS_QNX6) && !defined (P_OS_UNIX) && \
+ !defined (P_OS_LINUX) && !defined (P_OS_WIN) && !defined (P_OS_CYGWIN) && \
+ !defined (P_OS_SCO) && !defined (P_OS_UNIXWARE) && !defined (P_OS_VMS) && \
+ !defined (P_OS_IRIX) && !defined (P_OS_MSYS) && !defined (P_OS_DRAGONFLY) && \
+ !defined (P_OS_HAIKU) && !defined (P_OS_TRU64) && !defined (P_OS_SYLLABLE) && \
+ !defined (P_OS_BEOS) && !defined (P_OS_OS2) && !defined (P_OS_AMIGA)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for Mac OS */
+#if defined (P_OS_MAC9) && defined (P_OS_UNIX)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC9) && defined (P_OS_MAC)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC) && !defined (P_OS_MAC32) && !defined (P_OS_MAC64)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC) && (!defined (P_OS_DARWIN) || !defined (P_OS_BSD4))
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC32) && !defined (P_OS_DARWIN32)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC64) && !defined (P_OS_DARWIN64)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_MAC32) && defined (P_OS_MAC64)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for Windows */
+#if defined (P_OS_WIN64) && !defined (P_OS_WIN)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_OS_WIN) && defined (P_OS_UNIX)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for FreeBSD */
+#if defined (P_OS_FREEBSD) && !defined (P_OS_BSD4)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for DragonFlyBSD */
+#if defined (P_OS_DRAGONFLY) && !defined (P_OS_BSD4)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for NetBSD */
+#if defined (P_OS_NETBSD) && !defined (P_OS_BSD4)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for OpenBSD */
+#if defined (P_OS_OPENBSD) && !defined (P_OS_BSD4)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for Android */
+#if defined (P_OS_ANDROID) && !defined (P_OS_LINUX)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test for others */
+#if defined (P_OS_HAIKU) || defined (P_OS_BEOS) || defined (P_OS_OS2) || defined (P_OS_VMS) || \
+ defined (P_OS_AMIGA)
+# if defined (P_OS_UNIX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+ /* Test for compiler detection macros */
+#if !defined (P_CC_MSVC) && !defined (P_CC_GNU) && !defined (P_CC_MINGW) && \
+ !defined (P_CC_INTEL) && !defined (P_CC_CLANG) && !defined (P_CC_SUN) && \
+ !defined (P_CC_XLC) && !defined (P_CC_HP) && !defined (P_CC_WATCOM) && \
+ !defined (P_CC_BORLAND) && !defined (P_CC_MIPS) && !defined (P_CC_USLC) && \
+ !defined (P_CC_DEC) && !defined (P_CC_PGI) && !defined (P_CC_CRAY)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_CC_MSVC)
+# if !defined (P_OS_WIN)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_INTEL)
+# if !defined (P_OS_WIN) && !defined (P_OS_MAC) && \
+ !defined (P_OS_LINUX) && !defined (P_OS_FREEBSD) && \
+ !defined (P_OS_QNX6)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_SUN)
+# if !defined (P_OS_SOLARIS) && !defined (P_OS_LINUX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_XLC)
+# if !defined (P_OS_AIX) && !defined (P_OS_LINUX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_HP)
+# if !defined (P_OS_HPUX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_WATCOM)
+# if !defined (P_OS_WIN) && !defined (P_OS_LINUX) && \
+ !defined (P_OS_OS2) && !defined (P_OS_QNX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_BORLAND)
+# if !defined (P_OS_WIN)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_MIPS)
+# if !defined (P_OS_IRIX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_USLC)
+# if !defined (P_OS_SCO) && !defined (P_OS_UNIXWARE)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_DEC)
+# if !defined (P_OS_VMS) && !defined (P_OS_TRU64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_PGI)
+# if !defined (P_OS_WIN) && !defined (P_OS_MAC) && !defined (P_OS_LINUX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_CRAY)
+# if !defined (P_OS_LINUX)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+ /* Test for CPU architecture detection macros */
+#if defined (P_OS_VMS)
+# if !defined (P_CPU_ALPHA) && !defined (P_CPU_IA64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_AMIGA)
+# if !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_TRU64)
+# if !defined (P_CPU_ALPHA)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_AIX)
+# if !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_HPUX)
+# if !defined (P_CPU_HPPA) && !defined (P_CPU_IA64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_SOLARIS)
+# if !defined (P_CPU_X86) && !defined (P_CPU_SPARC) && !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_QNX)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_QNX6)
+# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && \
+ !defined (P_CPU_MIPS) && !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_BB10)
+# if !defined(P_CPU_X86) && !defined (P_CPU_ARM)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_SCO)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_UNIXWARE)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_IRIX)
+# if !defined (P_CPU_MIPS)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_HAIKU)
+# if !defined (P_CPU_X86) && !defined (P_CPU_ARM)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_SYLLABLE)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_BEOS)
+# if !defined (P_CPU_X86) && !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_OS2)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_MAC9)
+# if !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_MAC)
+# if !defined (P_CPU_X86) && !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_WIN)
+# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_IA64) && \
+ !defined (P_CPU_MIPS) && !defined (P_CPU_POWER) && !defined (P_CPU_ALPHA)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_OS_ANDROID)
+# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_MIPS)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_MSVC)
+# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_IA64) && \
+ !defined (P_CPU_MIPS) && !defined (P_CPU_POWER) && !defined (P_CPU_ALPHA)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_SUN)
+# if !defined (P_CPU_X86) && !defined (P_CPU_SPARC)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_XLC)
+# if !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_HP)
+# if !defined (P_CPU_HPPA) && !defined (P_CPU_IA64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_DEC)
+# if !defined (P_CPU_ALPHA) && !defined (P_CPU_IA64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_MIPS)
+# if !defined (P_CPU_MIPS)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_USLC)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_WATCOM)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_BORLAND)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CC_PGI)
+# if !defined (P_CPU_X86) && !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM)
+# if !defined (P_CPU_ARM_V2) && !defined (P_CPU_ARM_V3) && !defined (P_CPU_ARM_V4) && \
+ !defined (P_CPU_ARM_V5) && !defined (P_CPU_ARM_V6) && !defined (P_CPU_ARM_V7) && \
+ !defined (P_CPU_ARM_V8)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V2)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 2)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V3)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 3)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V4)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 4)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V5)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 5)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V6)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 6)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V7)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 7)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_V8)
+# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 8)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM) && !(P_CPU_ARM - 0 > 0)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_CPU_ARM)
+# if !defined (P_CPU_ARM_32) && !defined (P_CPU_ARM_64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_32) || defined (P_CPU_ARM_64)
+# if !defined (P_CPU_ARM)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_32)
+# ifdef P_CPU_ARM_64
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_ARM_64)
+# ifdef P_CPU_ARM_32
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_X86)
+# if !((P_CPU_X86 >= 3) && (P_CPU_X86 <= 6))
+ P_TEST_CHECK (false);
+# endif
+# if !defined (P_CPU_X86_32) && !defined (P_CPU_X86_64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_X86_32) || defined (P_CPU_X86_64)
+# if !defined (P_CPU_X86)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_X86_32) && defined (P_CPU_X86_64)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_CPU_X86_64)
+# if !defined (P_CPU_X86) || !(P_CPU_X86 - 0 == 6)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS)
+# if !defined (P_CPU_MIPS_I) && !defined (P_CPU_MIPS_II) && !defined (P_CPU_MIPS_III) && \
+ !defined (P_CPU_MIPS_IV) && !defined (P_CPU_MIPS_V) && !defined (P_CPU_MIPS_32) && \
+ !defined (P_CPU_MIPS_64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_I) || defined (P_CPU_MIPS_II) || defined (P_CPU_MIPS_III) || \
+ defined (P_CPU_MIPS_IV) || defined (P_CPU_MIPS_V) || defined (P_CPU_MIPS_32) || \
+ defined (P_CPU_MIPS_64)
+# if !defined (P_CPU_MIPS)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_II)
+# if !defined (P_CPU_MIPS_I)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_III)
+# if !defined (P_CPU_MIPS_II)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_IV)
+# if !defined (P_CPU_MIPS_III)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_V)
+# if !defined (P_CPU_MIPS_IV)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_32)
+# if !defined (P_CPU_MIPS_II)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_MIPS_64)
+# if !defined (P_CPU_MIPS_V)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_POWER)
+# if !defined (P_CPU_POWER_32) && !defined (P_CPU_POWER_64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_POWER_32) || defined (P_CPU_POWER_64)
+# if !defined (P_CPU_POWER)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_POWER_32) && defined (P_CPU_POWER_64)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_CPU_SPARC_V8) || defined (P_CPU_SPARC_V9)
+# if !defined (P_CPU_SPARC)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_SPARC_V8) && defined (P_CPU_SPARC_V9)
+ P_TEST_CHECK (false);
+#endif
+
+#if defined (P_CPU_HPPA)
+# if !defined (P_CPU_HPPA_32) && !defined (P_CPU_HPPA_64)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_HPPA_32) || defined (P_CPU_HPPA_64)
+# if !defined (P_CPU_HPPA)
+ P_TEST_CHECK (false);
+# endif
+#endif
+
+#if defined (P_CPU_HPPA_32) && defined (P_CPU_HPPA_64)
+ P_TEST_CHECK (false);
+#endif
+
+ /* Test other macros */
+ pint unused;
+ P_UNUSED (unused);
+
+ pint result = unused_result_test_func ();
+
+ P_UNUSED (result);
+
+ P_TEST_CHECK (internal_api_test () == 0);
+ P_TEST_CHECK (global_api_test () == 0);
+
+ P_WARNING ("Test warning output");
+ P_ERROR ("Test error output");
+ P_DEBUG ("Test debug output");
+
+ srand ((unsigned int) time (NULL));
+
+ pint rand_number = rand ();
+
+ if (P_LIKELY (rand_number > 0))
+ P_DEBUG ("Likely condition triggered");
+
+ if (P_UNLIKELY (rand_number == 0))
+ P_DEBUG ("Unlikely condition triggered");
+
+ /* Test version macros */
+ P_TEST_CHECK (PLIBSYS_VERSION_MAJOR >= 0);
+ P_TEST_CHECK (PLIBSYS_VERSION_MINOR >= 0);
+ P_TEST_CHECK (PLIBSYS_VERSION_PATCH >= 0);
+ P_TEST_CHECK (PLIBSYS_VERSION >= 0);
+
+#if !defined (PLIBSYS_VERSION_STR)
+ P_TEST_CHECK (false);
+#endif
+
+ P_TEST_CHECK (PLIBSYS_VERSION >= PLIBSYS_VERSION_CHECK (0, 0, 1));
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pmacros_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pmain_test.cpp b/3rdparty/plibsys/tests/pmain_test.cpp
new file mode 100644
index 0000000..ec1b553
--- /dev/null
+++ b/3rdparty/plibsys/tests/pmain_test.cpp
@@ -0,0 +1,111 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+static pint alloc_counter = 0;
+static pint realloc_counter = 0;
+static pint free_counter = 0;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ ++alloc_counter;
+ return (ppointer) malloc (nbytes);
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ ++realloc_counter;
+ return (ppointer) realloc (block, nbytes);
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ ++free_counter;
+ free (block);
+}
+
+P_TEST_CASE_BEGIN (pmain_general_test)
+{
+ p_libsys_init ();
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pmain_double_test)
+{
+ p_libsys_init_full (NULL);
+ p_libsys_init ();
+ p_libsys_shutdown ();
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pmain_vtable_test)
+{
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ p_libsys_init_full (&vtable);
+
+ alloc_counter = 0;
+ realloc_counter = 0;
+ free_counter = 0;
+
+ pchar *buf = (pchar *) p_malloc0 (10);
+ pchar *new_buf = (pchar *) p_realloc ((ppointer) buf, 20);
+
+ P_TEST_REQUIRE (new_buf != NULL);
+
+ buf = new_buf;
+
+ p_free (buf);
+
+ P_TEST_CHECK (alloc_counter > 0);
+ P_TEST_CHECK (realloc_counter > 0);
+ P_TEST_CHECK (free_counter > 0);
+
+ P_TEST_CHECK (strcmp (p_libsys_version (), PLIBSYS_VERSION_STR) == 0);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pmain_general_test);
+ P_TEST_SUITE_RUN_CASE (pmain_double_test);
+ P_TEST_SUITE_RUN_CASE (pmain_vtable_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pmem_test.cpp b/3rdparty/plibsys/tests/pmem_test.cpp
new file mode 100644
index 0000000..c9504b6
--- /dev/null
+++ b/3rdparty/plibsys/tests/pmem_test.cpp
@@ -0,0 +1,171 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+static pint alloc_counter = 0;
+static pint realloc_counter = 0;
+static pint free_counter = 0;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ ++alloc_counter;
+ return (ppointer) malloc (nbytes);
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ ++realloc_counter;
+ return (ppointer) realloc (block, nbytes);
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ ++free_counter;
+ free (block);
+}
+
+P_TEST_CASE_BEGIN (pmem_bad_input_test)
+{
+ PMemVTable vtable;
+
+ p_libsys_init ();
+
+ vtable.free = NULL;
+ vtable.malloc = NULL;
+ vtable.realloc = NULL;
+
+ P_TEST_CHECK (p_malloc (0) == NULL);
+ P_TEST_CHECK (p_malloc0 (0) == NULL);
+ P_TEST_CHECK (p_realloc (NULL, 0) == NULL);
+ P_TEST_CHECK (p_mem_set_vtable (NULL) == FALSE);
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == FALSE);
+ p_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pmem_general_test)
+{
+ PMemVTable vtable;
+ ppointer ptr = NULL;
+ pint i;
+
+ p_libsys_init ();
+
+ alloc_counter = 0;
+ realloc_counter = 0;
+ free_counter = 0;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ /* Test memory allocation using system functions */
+ ptr = p_malloc (1024);
+ P_TEST_REQUIRE (ptr != NULL);
+
+ for (int i = 0; i < 1024; ++i)
+ *(((pchar *) ptr) + i) = (pchar) (i % 127);
+
+ for (int i = 0; i < 1024; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127));
+
+ p_free (ptr);
+
+ ptr = p_malloc0 (2048);
+ P_TEST_REQUIRE (ptr != NULL);
+
+ for (int i = 0; i < 2048; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == 0);
+
+ for (int i = 0; i < 2048; ++i)
+ *(((pchar *) ptr) + i) = (pchar) (i % 127);
+
+ for (int i = 0; i < 2048; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127));
+
+ p_free (ptr);
+
+ ptr = p_realloc (NULL, 1024);
+ P_TEST_REQUIRE (ptr != NULL);
+
+ for (int i = 0; i < 1024; ++i)
+ *(((pchar *) ptr) + i) = (pchar) (i % 127);
+
+ ptr = p_realloc (ptr, 2048);
+
+ for (int i = 1024; i < 2048; ++i)
+ *(((pchar *) ptr) + i) = (pchar) ((i - 1) % 127);
+
+ for (int i = 0; i < 1024; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127));
+
+ for (int i = 1024; i < 2048; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) ((i - 1) % 127));
+
+ p_free (ptr);
+
+ P_TEST_CHECK (alloc_counter > 0);
+ P_TEST_CHECK (realloc_counter > 0);
+ P_TEST_CHECK (free_counter > 0);
+
+ p_mem_restore_vtable ();
+
+ /* Test memory mapping */
+ ptr = p_mem_mmap (0, NULL);
+ P_TEST_CHECK (ptr == NULL);
+
+ ptr = p_mem_mmap (1024, NULL);
+ P_TEST_REQUIRE (ptr != NULL);
+
+ for (i = 0; i < 1024; ++i)
+ *(((pchar *) ptr) + i) = i % 127;
+
+ for (i = 0; i < 1024; ++i)
+ P_TEST_CHECK (*(((pchar *) ptr) + i) == i % 127);
+
+ P_TEST_CHECK (p_mem_munmap (NULL, 1024, NULL) == FALSE);
+ P_TEST_CHECK (p_mem_munmap (ptr, 1024, NULL) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pmem_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pmem_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pmutex_test.cpp b/3rdparty/plibsys/tests/pmutex_test.cpp
new file mode 100644
index 0000000..4d16909
--- /dev/null
+++ b/3rdparty/plibsys/tests/pmutex_test.cpp
@@ -0,0 +1,146 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+static pint mutex_test_val = 0;
+static PMutex *global_mutex = NULL;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void * mutex_test_thread (void *)
+{
+ pint i;
+
+ for (i = 0; i < 1000; ++i) {
+ if (!p_mutex_trylock (global_mutex)) {
+ if (!p_mutex_lock (global_mutex))
+ p_uthread_exit (1);
+ }
+
+ if (mutex_test_val == 10)
+ --mutex_test_val;
+ else {
+ p_uthread_sleep (1);
+ ++mutex_test_val;
+ }
+
+ if (!p_mutex_unlock (global_mutex))
+ p_uthread_exit (1);
+ }
+
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (pmutex_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+ P_TEST_CHECK (p_mutex_new () == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pmutex_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_REQUIRE (p_mutex_lock (NULL) == FALSE);
+ P_TEST_REQUIRE (p_mutex_unlock (NULL) == FALSE);
+ P_TEST_REQUIRE (p_mutex_trylock (NULL) == FALSE);
+ p_mutex_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pmutex_general_test)
+{
+ PUThread *thr1, *thr2;
+
+ p_libsys_init ();
+
+ global_mutex = p_mutex_new ();
+ P_TEST_REQUIRE (global_mutex != NULL);
+
+ mutex_test_val = 10;
+
+ thr1 = p_uthread_create ((PUThreadFunc) mutex_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) mutex_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+
+ P_TEST_REQUIRE (mutex_test_val == 10);
+
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+ p_mutex_free (global_mutex);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pmutex_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pmutex_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pmutex_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pprocess_test.cpp b/3rdparty/plibsys/tests/pprocess_test.cpp
new file mode 100644
index 0000000..c58cf13
--- /dev/null
+++ b/3rdparty/plibsys/tests/pprocess_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+P_TEST_CASE_BEGIN (pprocess_general_test)
+{
+ puint32 pid;
+
+ p_libsys_init ();
+
+ pid = p_process_get_current_pid ();
+ P_TEST_CHECK (pid > 0);
+ P_TEST_REQUIRE (p_process_is_running (pid) == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pprocess_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/prwlock_test.cpp b/3rdparty/plibsys/tests/prwlock_test.cpp
new file mode 100644
index 0000000..c8bce38
--- /dev/null
+++ b/3rdparty/plibsys/tests/prwlock_test.cpp
@@ -0,0 +1,224 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PRWLOCK_TEST_STRING_1 "This is a test string."
+#define PRWLOCK_TEST_STRING_2 "Ouh, yet another string to check!"
+
+static PRWLock * test_rwlock = NULL;
+static volatile pboolean is_threads_working = FALSE;
+static volatile pint writers_counter = 0;
+static pchar string_buf[50];
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void * reader_thread_func (void *data)
+{
+ P_UNUSED (data);
+
+ pint counter = 0;
+
+ while (p_atomic_int_get (&writers_counter) == 0)
+ p_uthread_sleep (10);
+
+ while (is_threads_working == TRUE) {
+ p_uthread_sleep (10);
+
+ if (p_rwlock_reader_trylock (test_rwlock) == FALSE) {
+ if (p_rwlock_reader_lock (test_rwlock) == FALSE)
+ p_uthread_exit (-1);
+ }
+
+ if (strcmp (string_buf, PRWLOCK_TEST_STRING_1) != 0 &&
+ strcmp (string_buf, PRWLOCK_TEST_STRING_2) != 0) {
+ p_rwlock_reader_unlock (test_rwlock);
+ p_uthread_exit (-1);
+ }
+
+ if (p_rwlock_reader_unlock (test_rwlock) == FALSE)
+ p_uthread_exit (-1);
+
+ ++counter;
+ }
+
+ p_uthread_exit (counter);
+
+ return NULL;
+}
+
+static void * writer_thread_func (void *data)
+{
+ pint string_num = PPOINTER_TO_INT (data);
+ pint counter = 0;
+
+ while (is_threads_working == TRUE) {
+ p_uthread_sleep (10);
+
+ if (p_rwlock_writer_trylock (test_rwlock) == FALSE) {
+ if (p_rwlock_writer_lock (test_rwlock) == FALSE)
+ p_uthread_exit (-1);
+ }
+
+ memset (string_buf, 0, sizeof (string_buf));
+
+ if (string_num == 1)
+ strcpy (string_buf, PRWLOCK_TEST_STRING_1);
+ else
+ strcpy (string_buf, PRWLOCK_TEST_STRING_1);
+
+ if (p_rwlock_writer_unlock (test_rwlock) == FALSE)
+ p_uthread_exit (-1);
+
+ ++counter;
+
+ p_atomic_int_inc ((&writers_counter));
+ }
+
+ p_uthread_exit (counter);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (prwlock_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_rwlock_new () == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (prwlock_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_rwlock_reader_lock (NULL) == FALSE);
+ P_TEST_CHECK (p_rwlock_reader_trylock (NULL) == FALSE);
+ P_TEST_CHECK (p_rwlock_reader_unlock (NULL) == FALSE);
+ P_TEST_CHECK (p_rwlock_writer_lock (NULL) == FALSE);
+ P_TEST_CHECK (p_rwlock_writer_trylock (NULL) == FALSE);
+ P_TEST_CHECK (p_rwlock_writer_unlock (NULL) == FALSE);
+ p_rwlock_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (prwlock_general_test)
+{
+ p_libsys_init ();
+
+ test_rwlock = p_rwlock_new ();
+
+ P_TEST_REQUIRE (test_rwlock != NULL);
+
+ is_threads_working = TRUE;
+ writers_counter = 0;
+
+ PUThread *reader_thr1 = p_uthread_create ((PUThreadFunc) reader_thread_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ PUThread *reader_thr2 = p_uthread_create ((PUThreadFunc) reader_thread_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ PUThread *writer_thr1 = p_uthread_create ((PUThreadFunc) writer_thread_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ PUThread *writer_thr2 = p_uthread_create ((PUThreadFunc) writer_thread_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ P_TEST_REQUIRE (reader_thr1 != NULL);
+ P_TEST_REQUIRE (reader_thr2 != NULL);
+ P_TEST_REQUIRE (writer_thr1 != NULL);
+ P_TEST_REQUIRE (writer_thr2 != NULL);
+
+ p_uthread_sleep (10000);
+
+ is_threads_working = FALSE;
+
+ P_TEST_CHECK (p_uthread_join (reader_thr1) > 0);
+ P_TEST_CHECK (p_uthread_join (reader_thr2) > 0);
+ P_TEST_CHECK (p_uthread_join (writer_thr1) > 0);
+ P_TEST_CHECK (p_uthread_join (writer_thr2) > 0);
+
+ p_uthread_unref (reader_thr1);
+ p_uthread_unref (reader_thr2);
+ p_uthread_unref (writer_thr1);
+ p_uthread_unref (writer_thr2);
+
+ p_rwlock_free (test_rwlock);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (prwlock_nomem_test);
+ P_TEST_SUITE_RUN_CASE (prwlock_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (prwlock_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/psemaphore_test.cpp b/3rdparty/plibsys/tests/psemaphore_test.cpp
new file mode 100644
index 0000000..0b445bd
--- /dev/null
+++ b/3rdparty/plibsys/tests/psemaphore_test.cpp
@@ -0,0 +1,226 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+#define PSEMAPHORE_MAX_VAL 10
+
+static pint semaphore_test_val = 0;
+static pint is_thread_exit = 0;
+
+static void clean_error (PError **error)
+{
+ if (error == NULL || *error == NULL)
+ return;
+
+ p_error_free (*error);
+ *error = NULL;
+}
+
+static void * semaphore_test_thread (void *)
+{
+ PSemaphore *sem;
+ pint i;
+
+ sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN, NULL);
+
+ if (sem == NULL)
+ p_uthread_exit (1);
+
+ for (i = 0; i < 1000; ++i) {
+ if (!p_semaphore_acquire (sem, NULL)) {
+ if (is_thread_exit > 0) {
+ semaphore_test_val = PSEMAPHORE_MAX_VAL;
+ break;
+ }
+
+ p_uthread_exit (1);
+ }
+
+ if (semaphore_test_val == PSEMAPHORE_MAX_VAL)
+ --semaphore_test_val;
+ else {
+ p_uthread_sleep (1);
+ ++semaphore_test_val;
+ }
+
+ if (!p_semaphore_release (sem, NULL)) {
+ if (is_thread_exit > 0) {
+ semaphore_test_val = PSEMAPHORE_MAX_VAL;
+ break;
+ }
+
+ p_uthread_exit (1);
+ }
+ }
+
+ ++is_thread_exit;
+
+ p_semaphore_free (sem);
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (psemaphore_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_CREATE, NULL) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psemaphore_general_test)
+{
+ PSemaphore *sem = NULL;
+ PError *error = NULL;
+ pint i;
+
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_semaphore_new (NULL, 0, P_SEM_ACCESS_CREATE, &error) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_REQUIRE (p_semaphore_acquire (sem, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_REQUIRE (p_semaphore_release (sem, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ p_semaphore_take_ownership (sem);
+ p_semaphore_free (NULL);
+
+ sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL);
+ P_TEST_REQUIRE (sem != NULL);
+ p_semaphore_take_ownership (sem);
+ p_semaphore_free (sem);
+
+ sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL);
+ P_TEST_REQUIRE (sem != NULL);
+
+ for (i = 0; i < 10; ++i)
+ P_TEST_CHECK (p_semaphore_acquire (sem, NULL));
+
+ for (i = 0; i < 10; ++i)
+ P_TEST_CHECK (p_semaphore_release (sem, NULL));
+
+ for (i = 0; i < 1000; ++i) {
+ P_TEST_CHECK (p_semaphore_acquire (sem, NULL));
+ P_TEST_CHECK (p_semaphore_release (sem, NULL));
+ }
+
+ p_semaphore_free (sem);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psemaphore_thread_test)
+{
+ PUThread *thr1, *thr2;
+ PSemaphore *sem = NULL;
+
+ p_libsys_init ();
+
+ sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL);
+ P_TEST_REQUIRE (sem != NULL);
+ p_semaphore_take_ownership (sem);
+ p_semaphore_free (sem);
+
+ sem = NULL;
+ is_thread_exit = 0;
+ semaphore_test_val = PSEMAPHORE_MAX_VAL;
+
+ thr1 = p_uthread_create ((PUThreadFunc) semaphore_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) semaphore_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+
+ P_TEST_REQUIRE (semaphore_test_val == PSEMAPHORE_MAX_VAL);
+
+ P_TEST_REQUIRE (p_semaphore_acquire (sem, NULL) == FALSE);
+ P_TEST_REQUIRE (p_semaphore_release (sem, NULL) == FALSE);
+ p_semaphore_free (sem);
+ p_semaphore_take_ownership (sem);
+
+ sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN, NULL);
+ P_TEST_REQUIRE (sem != NULL);
+ p_semaphore_take_ownership (sem);
+ p_semaphore_free (sem);
+
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (psemaphore_nomem_test);
+ P_TEST_SUITE_RUN_CASE (psemaphore_general_test);
+ P_TEST_SUITE_RUN_CASE (psemaphore_thread_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pshm_test.cpp b/3rdparty/plibsys/tests/pshm_test.cpp
new file mode 100644
index 0000000..bc89692
--- /dev/null
+++ b/3rdparty/plibsys/tests/pshm_test.cpp
@@ -0,0 +1,313 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <time.h>
+
+P_TEST_MODULE_INIT ();
+
+static void * shm_test_thread (void *arg)
+{
+ pint rand_num;
+ psize shm_size;
+ ppointer addr;
+ PShm *shm;
+
+ if (arg == NULL)
+ p_uthread_exit (1);
+
+ shm = (PShm *) arg;
+ rand_num = rand () % 127;
+ shm_size = p_shm_get_size (shm);
+ addr = p_shm_get_address (shm);
+
+ if (shm_size == 0 || addr == NULL)
+ p_uthread_exit (1);
+
+ if (!p_shm_lock (shm, NULL))
+ p_uthread_exit (1);
+
+ for (puint i = 0; i < shm_size; ++i)
+ *(((pchar *) addr) + i) = (pchar) rand_num;
+
+ if (!p_shm_unlock (shm, NULL))
+ p_uthread_exit (1);
+
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (pshm_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pshm_invalid_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_shm_new (NULL, 0, P_SHM_ACCESS_READWRITE, NULL) == NULL);
+ P_TEST_CHECK (p_shm_lock (NULL, NULL) == FALSE);
+ P_TEST_CHECK (p_shm_unlock (NULL, NULL) == FALSE);
+ P_TEST_CHECK (p_shm_get_address (NULL) == NULL);
+ P_TEST_CHECK (p_shm_get_size (NULL) == 0);
+ p_shm_take_ownership (NULL);
+
+ PShm *shm = p_shm_new ("p_shm_invalid_test", 0, P_SHM_ACCESS_READWRITE, NULL);
+ p_shm_take_ownership (shm);
+ p_shm_free (shm);
+
+ shm = p_shm_new ("p_shm_invalid_test", 10, (PShmAccessPerms) -1, NULL);
+ p_shm_take_ownership (shm);
+ p_shm_free (shm);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pshm_general_test)
+{
+ PShm *shm = NULL;
+#ifndef P_OS_HPUX
+ PShm *shm2 = NULL;
+#endif
+ ppointer addr, addr2;
+ pint i;
+
+ p_libsys_init ();
+
+ shm = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+ p_shm_take_ownership (shm);
+ p_shm_free (shm);
+
+ shm = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+ P_TEST_REQUIRE (p_shm_get_size (shm) == 1024);
+
+ addr = p_shm_get_address (shm);
+ P_TEST_REQUIRE (addr != NULL);
+
+#ifndef P_OS_HPUX
+ shm2 = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READONLY, NULL);
+
+ if (shm2 == NULL) {
+ /* OK, some systems may want exactly the same permissions */
+ shm2 = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL);
+ }
+
+ P_TEST_REQUIRE (shm2 != NULL);
+ P_TEST_REQUIRE (p_shm_get_size (shm2) == 1024);
+
+ addr2 = p_shm_get_address (shm2);
+ P_TEST_REQUIRE (addr2 != NULL);
+#endif
+
+ for (i = 0; i < 512; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ *(((pchar *) addr) + i) = 'a';
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+
+#ifndef P_OS_HPUX
+ for (i = 0; i < 512; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm2, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) == 'a');
+ P_TEST_CHECK (p_shm_unlock (shm2, NULL));
+ }
+#else
+ for (i = 0; i < 512; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) == 'a');
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+#endif
+
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ *(((pchar *) addr) + i) = 'b';
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+
+#ifndef P_OS_HPUX
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm2, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) != 'c');
+ P_TEST_CHECK (p_shm_unlock (shm2, NULL));
+ }
+
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm2, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) == 'b');
+ P_TEST_CHECK (p_shm_unlock (shm2, NULL));
+ }
+#else
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) != 'c');
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) == 'b');
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+#endif
+
+ p_shm_free (shm);
+
+ shm = p_shm_new ("p_shm_test_memory_block_2", 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+ P_TEST_REQUIRE (p_shm_get_size (shm) == 1024);
+
+ addr = p_shm_get_address (shm);
+ P_TEST_REQUIRE (addr != NULL);
+
+ for (i = 0; i < 1024; ++i) {
+ P_TEST_CHECK (p_shm_lock (shm, NULL));
+ P_TEST_CHECK (*(((pchar *) addr) + i) != 'b');
+ P_TEST_CHECK (p_shm_unlock (shm, NULL));
+ }
+
+ p_shm_free (shm);
+
+#ifndef P_OS_HPUX
+ p_shm_free (shm2);
+#endif
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pshm_thread_test)
+{
+ PShm *shm;
+ PUThread *thr1, *thr2, *thr3;
+ ppointer addr;
+ pint i, val;
+ pboolean test_ok;
+
+ p_libsys_init ();
+
+ srand ((puint) time (NULL));
+
+ shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+ p_shm_take_ownership (shm);
+ p_shm_free (shm);
+
+ shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+
+ if (p_shm_get_size (shm) != 1024 * 1024) {
+ p_shm_free (shm);
+ shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL);
+ P_TEST_REQUIRE (shm != NULL);
+ }
+
+ P_TEST_REQUIRE (p_shm_get_size (shm) == 1024 * 1024);
+
+ addr = p_shm_get_address (shm);
+ P_TEST_REQUIRE (addr != NULL);
+
+ thr1 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ thr3 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL);
+ P_TEST_REQUIRE (thr3 != NULL);
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+ P_TEST_CHECK (p_uthread_join (thr3) == 0);
+
+ test_ok = TRUE;
+ val = *((pchar *) addr);
+
+ for (i = 1; i < 1024 * 1024; ++i)
+ if (*(((pchar *) addr) + i) != val) {
+ test_ok = FALSE;
+ break;
+ }
+
+ P_TEST_REQUIRE (test_ok == TRUE);
+
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+ p_uthread_unref (thr3);
+ p_shm_free (shm);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pshm_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pshm_invalid_test);
+ P_TEST_SUITE_RUN_CASE (pshm_general_test);
+ P_TEST_SUITE_RUN_CASE (pshm_thread_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pshmbuffer_test.cpp b/3rdparty/plibsys/tests/pshmbuffer_test.cpp
new file mode 100644
index 0000000..7e48f56
--- /dev/null
+++ b/3rdparty/plibsys/tests/pshmbuffer_test.cpp
@@ -0,0 +1,352 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2020 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+static pchar test_str[] = "This is a test string!";
+static pchar test_str_sm[] = "Small";
+static pint is_thread_exit = 0;
+static pint read_count = 0;
+static pint write_count = 0;
+
+#ifndef P_OS_HPUX
+volatile static pboolean is_working = FALSE;
+
+static void * shm_buffer_test_write_thread (void *)
+{
+ PShmBuffer *buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+
+ if (buffer == NULL)
+ p_uthread_exit (1);
+
+ while (is_working == TRUE) {
+ p_uthread_sleep (3);
+
+ pssize op_result = p_shm_buffer_get_free_space (buffer, NULL);
+
+ if (op_result < 0) {
+ if (is_thread_exit > 0)
+ break;
+ else {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+ }
+
+ if ((psize) op_result < sizeof (test_str))
+ continue;
+
+ op_result = p_shm_buffer_write (buffer, (ppointer) test_str, sizeof (test_str), NULL);
+
+ if (op_result < 0) {
+ if (is_thread_exit > 0)
+ break;
+ else {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+ }
+
+ if (op_result != sizeof (test_str)) {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+
+ ++read_count;
+ }
+
+ ++is_thread_exit;
+
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+static void * shm_buffer_test_read_thread (void *)
+{
+ PShmBuffer *buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+ pchar test_buf[sizeof (test_str)];
+
+ if (buffer == NULL)
+ p_uthread_exit (1);
+
+ while (is_working == TRUE) {
+ p_uthread_sleep (3);
+
+ pssize op_result = p_shm_buffer_get_used_space (buffer, NULL);
+
+ if (op_result < 0) {
+ if (is_thread_exit > 0)
+ break;
+ else {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+ }
+
+ if ((psize) op_result < sizeof (test_str))
+ continue;
+
+ op_result = p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL);
+
+ if (op_result < 0) {
+ if (is_thread_exit > 0)
+ break;
+ else {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+ }
+
+ if (op_result != sizeof (test_buf)) {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+
+ if (strncmp (test_buf, test_str, sizeof (test_buf)) != 0) {
+ ++is_thread_exit;
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (1);
+ }
+
+ ++write_count;
+ }
+
+ ++is_thread_exit;
+
+ p_shm_buffer_free (buffer);
+ p_uthread_exit (0);
+
+ return NULL;
+}
+#endif /* !P_OS_HPUX */
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (pshmbuffer_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_shm_buffer_new ("pshm_test_buffer", 1024, NULL) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pshmbuffer_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_shm_buffer_new (NULL, 0, NULL) == NULL);
+ P_TEST_CHECK (p_shm_buffer_read (NULL, NULL, 0, NULL) == -1);
+ P_TEST_CHECK (p_shm_buffer_write (NULL, NULL, 0, NULL) == -1);
+ P_TEST_CHECK (p_shm_buffer_get_free_space (NULL, NULL) == -1);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (NULL, NULL) == -1);
+
+ PShmBuffer *buf = p_shm_buffer_new ("pshm_invalid_buffer", 0, NULL);
+ p_shm_buffer_take_ownership (buf);
+ p_shm_buffer_free (buf);
+
+ p_shm_buffer_clear (NULL);
+ p_shm_buffer_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pshmbuffer_general_test)
+{
+ p_libsys_init ();
+
+ pchar test_buf[sizeof (test_str)];
+ pchar *large_buf;
+ PShmBuffer *buffer = NULL;
+
+ /* Buffer may be from the previous test on UNIX systems */
+ buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+ p_shm_buffer_take_ownership (buffer);
+ p_shm_buffer_free (buffer);
+ buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0);
+ p_shm_buffer_clear (buffer);
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0);
+
+ memset (test_buf, 0, sizeof (test_buf));
+
+ P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str, sizeof (test_str), NULL) == sizeof (test_str));
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (1024 - sizeof (test_str)));
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str));
+ P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == sizeof (test_str));
+ P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == 0);
+
+ P_TEST_CHECK (strncmp (test_buf, test_str, sizeof (test_str)) == 0);
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0);
+
+ p_shm_buffer_clear (buffer);
+
+ large_buf = (pchar *) p_malloc0 (2048);
+ P_TEST_REQUIRE (large_buf != NULL);
+ P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) large_buf, 2048, NULL) == 0);
+
+ p_free (large_buf);
+ p_shm_buffer_free (buffer);
+
+ /* Test read-write positions */
+
+ buffer = p_shm_buffer_new ("pshm_test_buffer_small", 10, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+ p_shm_buffer_take_ownership (buffer);
+ p_shm_buffer_free (buffer);
+ buffer = p_shm_buffer_new ("pshm_test_buffer_small", 10, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 10);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0);
+
+ /* Case 1: write position > read position */
+ P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str_sm, sizeof (test_str_sm), NULL) == sizeof (test_str_sm));
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (10 - sizeof (test_str_sm)));
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str_sm));
+
+ /* Case 2: write position == read position */
+ memset (test_buf, 0, sizeof (test_buf));
+ P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == sizeof (test_str_sm));
+ P_TEST_CHECK (strncmp (test_buf, test_str_sm, sizeof (test_str_sm)) == 0);
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 10);
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0);
+
+ /* Case 3: write position < read position */
+ P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str_sm, sizeof (test_str_sm), NULL) == sizeof (test_str_sm));
+ P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (10 - sizeof (test_str_sm)));
+ P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str_sm));
+
+ p_shm_buffer_free (buffer);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+#ifndef P_OS_HPUX
+P_TEST_CASE_BEGIN (pshmbuffer_thread_test)
+{
+ p_libsys_init ();
+
+ PShmBuffer *buffer = NULL;
+ PUThread *thr1, *thr2;
+
+ /* Buffer may be from the previous test on UNIX systems */
+ buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+ p_shm_buffer_take_ownership (buffer);
+ p_shm_buffer_free (buffer);
+
+ is_thread_exit = 0;
+ read_count = 0;
+ write_count = 0;
+ is_working = TRUE;
+
+ buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL);
+ P_TEST_REQUIRE (buffer != NULL);
+
+ thr1 = p_uthread_create ((PUThreadFunc) shm_buffer_test_write_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) shm_buffer_test_read_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ p_uthread_sleep (5000);
+
+ is_working = FALSE;
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+
+ P_TEST_CHECK (read_count > 0);
+ P_TEST_CHECK (write_count > 0);
+
+ p_shm_buffer_free (buffer);
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+#endif /* !P_OS_HPUX */
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pshmbuffer_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pshmbuffer_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pshmbuffer_general_test);
+
+#ifndef P_OS_HPUX
+ P_TEST_SUITE_RUN_CASE (pshmbuffer_thread_test);
+#endif
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/psocket_test.cpp b/3rdparty/plibsys/tests/psocket_test.cpp
new file mode 100644
index 0000000..c1a44a4
--- /dev/null
+++ b/3rdparty/plibsys/tests/psocket_test.cpp
@@ -0,0 +1,1131 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+static pchar socket_data[] = "This is a socket test data!";
+volatile static pboolean is_sender_working = FALSE;
+volatile static pboolean is_receiver_working = FALSE;
+
+typedef struct _SocketTestData {
+ puint16 sender_port;
+ puint16 receiver_port;
+ pboolean shutdown_channel;
+} SocketTestData;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void clean_error (PError **error)
+{
+ if (error == NULL || *error == NULL)
+ return;
+
+ p_error_free (*error);
+ *error = NULL;
+}
+
+static pboolean test_socket_address_directly (const PSocketAddress *addr, puint16 port)
+{
+ if (addr == NULL)
+ return FALSE;
+
+ pchar *addr_str = p_socket_address_get_address (addr);
+ PSocketFamily remote_family = p_socket_address_get_family (addr);
+ puint16 remote_port = p_socket_address_get_port (addr);
+ psize remote_size = p_socket_address_get_native_size (addr);
+
+ pboolean ret = (strcmp (addr_str, "127.0.0.1") == 0 && remote_family == P_SOCKET_FAMILY_INET &&
+ remote_port == port && remote_size > 0) ? TRUE : FALSE;
+
+ p_free (addr_str);
+
+ return ret;
+}
+
+static pboolean test_socket_address (PSocket *socket, puint16 port)
+{
+ /* Test remote address */
+ PSocketAddress *remote_addr = p_socket_get_remote_address (socket, NULL);
+
+ if (remote_addr == NULL)
+ return FALSE;
+
+ pboolean ret = test_socket_address_directly (remote_addr, port);
+
+ p_socket_address_free (remote_addr);
+
+ return ret;
+}
+
+static pboolean compare_socket_addresses (const PSocketAddress *addr1, const PSocketAddress *addr2)
+{
+ if (addr1 == NULL || addr2 == NULL)
+ return FALSE;
+
+ pchar *addr_str1 = p_socket_address_get_address (addr1);
+ pchar *addr_str2 = p_socket_address_get_address (addr2);
+
+ if (addr_str1 == NULL || addr_str2 == NULL) {
+ p_free (addr_str1);
+ p_free (addr_str2);
+
+ return FALSE;
+ }
+
+ pboolean addr_cmp = (strcmp (addr_str1, addr_str2) == 0 ? TRUE : FALSE);
+
+ p_free (addr_str1);
+ p_free (addr_str2);
+
+ if (addr_cmp == FALSE)
+ return FALSE;
+
+ if (p_socket_address_get_family (addr1) != p_socket_address_get_family (addr2))
+ return FALSE;
+
+ if (p_socket_address_get_native_size (addr1) != p_socket_address_get_native_size (addr2))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void * udp_socket_sender_thread (void *arg)
+{
+ pint send_counter = 0;
+
+ if (arg == NULL)
+ p_uthread_exit (-1);
+
+ SocketTestData *data = (SocketTestData *) (arg);
+
+ /* Create sender socket */
+ PSocket *skt_sender = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_DATAGRAM,
+ P_SOCKET_PROTOCOL_UDP,
+ NULL);
+
+ if (skt_sender == NULL)
+ p_uthread_exit (-1);
+
+ PSocketAddress *addr_sender = p_socket_address_new ("127.0.0.1", data->sender_port);
+
+ if (addr_sender == NULL) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ if (p_socket_bind (skt_sender, addr_sender, FALSE, NULL) == FALSE) {
+ p_socket_free (skt_sender);
+ p_socket_address_free (addr_sender);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (addr_sender);
+
+ PSocketAddress *local_addr = p_socket_get_local_address (skt_sender, NULL);
+
+ if (local_addr == NULL) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ data->sender_port = p_socket_address_get_port (local_addr);
+
+ p_socket_address_free (local_addr);
+ }
+
+ p_socket_set_timeout (skt_sender, 50);
+
+ /* Test that remote address is NULL */
+ PSocketAddress *remote_addr = p_socket_get_remote_address (skt_sender, NULL);
+
+ if (remote_addr != NULL) {
+ if (p_socket_address_is_any (remote_addr) == FALSE) {
+ p_socket_address_free (remote_addr);
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (remote_addr);
+ remote_addr = NULL;
+ }
+ }
+
+ /* Test that we are not connected */
+ if (p_socket_is_connected (skt_sender) == TRUE) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ while (is_sender_working == TRUE && data->receiver_port == 0) {
+ p_uthread_sleep (1);
+ continue;
+ }
+
+ PSocketAddress *addr_receiver = NULL;
+
+ if (data->receiver_port != 0)
+ addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port);
+
+ while (is_sender_working == TRUE) {
+ if (data->receiver_port == 0)
+ break;
+
+ if (p_socket_send_to (skt_sender,
+ addr_receiver,
+ socket_data,
+ sizeof (socket_data),
+ NULL) == sizeof (socket_data))
+ ++send_counter;
+
+ p_uthread_sleep (1);
+ }
+
+ p_socket_address_free (addr_receiver);
+ p_socket_free (skt_sender);
+ p_uthread_exit (send_counter);
+
+ return NULL;
+}
+
+static void * udp_socket_receiver_thread (void *arg)
+{
+ pchar recv_buffer[sizeof (socket_data) * 3];
+ pint recv_counter = 0;
+
+ if (arg == NULL)
+ p_uthread_exit (-1);
+
+ SocketTestData *data = (SocketTestData *) (arg);
+
+ /* Create receiving socket */
+ PSocket *skt_receiver = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_DATAGRAM,
+ P_SOCKET_PROTOCOL_UDP,
+ NULL);
+
+ if (skt_receiver == NULL)
+ p_uthread_exit (-1);
+
+ p_socket_set_blocking (skt_receiver, FALSE);
+
+ PSocketAddress *addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port);
+
+ if (addr_receiver == NULL) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ if (p_socket_bind (skt_receiver, addr_receiver, TRUE, NULL) == FALSE) {
+ p_socket_free (skt_receiver);
+ p_socket_address_free (addr_receiver);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (addr_receiver);
+
+ PSocketAddress *local_addr = p_socket_get_local_address (skt_receiver, NULL);
+
+ if (local_addr == NULL) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ data->receiver_port = p_socket_address_get_port (local_addr);
+
+ p_socket_address_free (local_addr);
+ }
+
+ p_socket_set_timeout (skt_receiver, 50);
+
+ /* Test that remote address is NULL */
+ PSocketAddress *remote_addr = p_socket_get_remote_address (skt_receiver, NULL);
+
+ if (remote_addr != NULL) {
+ if (p_socket_address_is_any (remote_addr) == FALSE) {
+ p_socket_address_free (remote_addr);
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (remote_addr);
+ remote_addr = NULL;
+ }
+ }
+
+ /* Test that we are not connected */
+ if (p_socket_is_connected (skt_receiver) == TRUE) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ while (is_receiver_working == TRUE) {
+ PSocketAddress *remote_addr = NULL;
+
+ pssize received = p_socket_receive_from (skt_receiver,
+ &remote_addr,
+ recv_buffer,
+ sizeof (recv_buffer),
+ NULL);
+
+ if (remote_addr != NULL && test_socket_address_directly (remote_addr, data->sender_port) == FALSE) {
+ p_socket_address_free (remote_addr);
+ break;
+ }
+
+ p_socket_address_free (remote_addr);
+
+ if (received == sizeof (socket_data))
+ ++recv_counter;
+ else if (received > 0) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ p_uthread_sleep (1);
+ }
+
+ p_socket_free (skt_receiver);
+ p_uthread_exit (recv_counter);
+
+ return NULL;
+}
+
+static void * tcp_socket_sender_thread (void *arg)
+{
+ pint send_counter = 0;
+ psize send_total;
+ pssize send_now;
+ pboolean is_connected = FALSE;
+
+ if (arg == NULL)
+ p_uthread_exit (-1);
+
+ SocketTestData *data = (SocketTestData *) (arg);
+
+ /* Create sender socket */
+ PSocket *skt_sender = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_STREAM,
+ P_SOCKET_PROTOCOL_DEFAULT,
+ NULL);
+
+ if (skt_sender == NULL)
+ p_uthread_exit (-1);
+
+ p_socket_set_timeout (skt_sender, 2000);
+
+ if (p_socket_get_fd (skt_sender) < 0) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ while (is_sender_working == TRUE && data->receiver_port == 0) {
+ p_uthread_sleep (1);
+ continue;
+ }
+
+ PSocketAddress *addr_sender = p_socket_address_new ("127.0.0.1", data->sender_port);
+
+ if (addr_sender == NULL) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ if (p_socket_bind (skt_sender, addr_sender, FALSE, NULL) == FALSE) {
+ p_socket_free (skt_sender);
+ p_socket_address_free (addr_sender);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (addr_sender);
+
+ PSocketAddress *local_addr = p_socket_get_local_address (skt_sender, NULL);
+
+ if (local_addr == NULL) {
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ data->sender_port = p_socket_address_get_port (local_addr);
+
+ p_socket_address_free (local_addr);
+ }
+
+ send_total = 0;
+ send_now = 0;
+
+ while (is_sender_working == TRUE && data->receiver_port == 0) {
+ p_uthread_sleep (1);
+ continue;
+ }
+
+ PSocketAddress *addr_receiver = NULL;
+
+ /* Try to connect in non-blocking mode */
+ p_socket_set_blocking (skt_sender, FALSE);
+
+ if (data->receiver_port != 0) {
+ addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port);
+ is_connected = p_socket_connect (skt_sender, addr_receiver, NULL);
+
+ if (is_connected == FALSE) {
+ if (p_socket_io_condition_wait (skt_sender, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == TRUE &&
+ p_socket_check_connect_result (skt_sender, NULL) == FALSE) {
+ p_socket_address_free (addr_receiver);
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+ }
+
+ is_connected = p_socket_is_connected (skt_sender);
+
+ if (is_connected == TRUE && p_socket_shutdown (skt_sender,
+ FALSE,
+ data->shutdown_channel,
+ NULL) == FALSE)
+ is_connected = FALSE;
+ }
+
+ if (data->shutdown_channel == TRUE && p_socket_is_closed (skt_sender) == TRUE) {
+ p_socket_address_free (addr_receiver);
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ p_socket_set_blocking (skt_sender, TRUE);
+
+ while (is_sender_working == TRUE) {
+ if (data->receiver_port == 0 || is_connected == FALSE)
+ break;
+
+ if (test_socket_address (skt_sender, data->receiver_port) == FALSE)
+ break;
+
+ if (data->shutdown_channel == FALSE && p_socket_is_connected (skt_sender) == FALSE) {
+ p_socket_address_free (addr_receiver);
+ p_socket_free (skt_sender);
+ p_uthread_exit (-1);
+ }
+
+ send_now = p_socket_send (skt_sender,
+ socket_data + send_total,
+ sizeof (socket_data) - send_total,
+ NULL);
+
+ if (send_now > 0)
+ send_total += (psize) send_now;
+
+ if (send_total == sizeof (socket_data)) {
+ send_total = 0;
+ ++send_counter;
+ }
+
+ p_uthread_sleep (1);
+ }
+
+ if (p_socket_close (skt_sender, NULL) == FALSE)
+ send_counter = -1;
+
+ p_socket_address_free (addr_receiver);
+ p_socket_free (skt_sender);
+ p_uthread_exit (send_counter);
+
+ return NULL;
+}
+
+static void * tcp_socket_receiver_thread (void *arg)
+{
+ pchar recv_buffer[sizeof (socket_data)];
+ pint recv_counter = 0;
+ psize recv_total;
+ pssize recv_now;
+
+ if (arg == NULL)
+ p_uthread_exit (-1);
+
+ SocketTestData *data = (SocketTestData *) (arg);
+
+ /* Create receiving socket */
+ PSocket *skt_receiver = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_STREAM,
+ P_SOCKET_PROTOCOL_TCP,
+ NULL);
+
+ if (skt_receiver == NULL)
+ p_uthread_exit (-1);
+
+ PSocketAddress *addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port);
+
+ if (addr_receiver == NULL) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ p_socket_set_timeout (skt_receiver, 2000);
+
+ if (p_socket_bind (skt_receiver, addr_receiver, TRUE, NULL) == FALSE ||
+ p_socket_listen (skt_receiver, NULL) == FALSE) {
+ p_socket_free (skt_receiver);
+ p_socket_address_free (addr_receiver);
+ p_uthread_exit (-1);
+ } else {
+ p_socket_address_free (addr_receiver);
+
+ PSocketAddress *local_addr = p_socket_get_local_address (skt_receiver, NULL);
+
+ if (local_addr == NULL) {
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ data->receiver_port = p_socket_address_get_port (local_addr);
+
+ p_socket_address_free (local_addr);
+ }
+
+ PSocket *conn_socket = NULL;
+ recv_total = 0;
+ recv_now = 0;
+
+ while (is_receiver_working == TRUE) {
+ if (conn_socket == NULL) {
+ conn_socket = p_socket_accept (skt_receiver, NULL);
+
+ if (conn_socket == NULL) {
+ p_uthread_sleep (1);
+ continue;
+ } else {
+ /* On Syllable there is a bug in TCP which changes a local port
+ * of the client socket which connects to a server */
+#ifndef P_OS_SYLLABLE
+ if (test_socket_address (conn_socket, data->sender_port) == FALSE)
+ break;
+#endif
+
+ if (p_socket_shutdown (conn_socket, data->shutdown_channel, FALSE, NULL) == FALSE)
+ break;
+
+ p_socket_set_timeout (conn_socket, 2000);
+ }
+ }
+
+ if ((data->shutdown_channel == FALSE && p_socket_is_connected (conn_socket) == FALSE) ||
+ (data->shutdown_channel == TRUE && p_socket_is_closed (conn_socket) == TRUE)) {
+ p_socket_free (conn_socket);
+ p_socket_free (skt_receiver);
+ p_uthread_exit (-1);
+ }
+
+ recv_now = p_socket_receive (conn_socket,
+ recv_buffer + recv_total,
+ sizeof (recv_buffer) - recv_total,
+ NULL);
+
+ if (recv_now > 0)
+ recv_total += (psize) recv_now;
+
+ if (recv_total == sizeof (recv_buffer)) {
+ recv_total = 0;
+
+ if (strncmp (recv_buffer, socket_data, sizeof (recv_buffer)) == 0)
+ ++recv_counter;
+
+ memset (recv_buffer, 0, sizeof (recv_buffer));
+ }
+
+ p_uthread_sleep (1);
+ }
+
+ if (p_socket_close (skt_receiver, NULL) == FALSE)
+ recv_counter = -1;
+
+ p_socket_free (conn_socket);
+ p_socket_free (skt_receiver);
+
+ p_uthread_exit (recv_counter);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (psocket_nomem_test)
+{
+ p_libsys_init ();
+
+ PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_DATAGRAM,
+ P_SOCKET_PROTOCOL_UDP,
+ NULL);
+ P_TEST_CHECK (socket != NULL);
+
+ PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 32211);
+
+ P_TEST_CHECK (sock_addr != NULL);
+ P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE);
+
+ p_socket_address_free (sock_addr);
+
+ p_socket_set_timeout (socket, 1000);
+ sock_addr = p_socket_address_new ("127.0.0.1", 32215);
+ P_TEST_CHECK (sock_addr != NULL);
+ P_TEST_CHECK (p_socket_connect (socket, sock_addr, NULL) == TRUE);
+
+ p_socket_address_free (sock_addr);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_DATAGRAM,
+ P_SOCKET_PROTOCOL_UDP,
+ NULL) == NULL);
+ P_TEST_CHECK (p_socket_new_from_fd (p_socket_get_fd (socket), NULL) == NULL);
+ P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL);
+ P_TEST_CHECK (p_socket_get_remote_address (socket, NULL) == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_socket_close (socket, NULL);
+ p_socket_free (socket);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_bad_input_test)
+{
+ p_libsys_init ();
+
+ PError *error = NULL;
+
+ P_TEST_CHECK (p_socket_new_from_fd (-1, &error) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_INET,
+ (PSocketType) -1,
+ P_SOCKET_PROTOCOL_TCP,
+ NULL) == NULL);
+ /* Syllable doesn't validate socket family */
+#ifndef P_OS_SYLLABLE
+ P_TEST_CHECK (p_socket_new ((PSocketFamily) -1,
+ P_SOCKET_TYPE_SEQPACKET,
+ P_SOCKET_PROTOCOL_TCP,
+ NULL) == NULL);
+#endif
+ P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_UNKNOWN,
+ P_SOCKET_TYPE_UNKNOWN,
+ P_SOCKET_PROTOCOL_UNKNOWN,
+ &error) == NULL);
+ P_TEST_CHECK (p_socket_new_from_fd (1, NULL) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_get_fd (NULL) == -1);
+ P_TEST_CHECK (p_socket_get_family (NULL) == P_SOCKET_FAMILY_UNKNOWN);
+ P_TEST_CHECK (p_socket_get_type (NULL) == P_SOCKET_TYPE_UNKNOWN);
+ P_TEST_CHECK (p_socket_get_protocol (NULL) == P_SOCKET_PROTOCOL_UNKNOWN);
+ P_TEST_CHECK (p_socket_get_keepalive (NULL) == FALSE);
+ P_TEST_CHECK (p_socket_get_blocking (NULL) == FALSE);
+ P_TEST_CHECK (p_socket_get_timeout (NULL) == -1);
+ P_TEST_CHECK (p_socket_get_listen_backlog (NULL) == -1);
+ P_TEST_CHECK (p_socket_io_condition_wait (NULL, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_io_condition_wait (NULL, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE);
+
+ P_TEST_CHECK (p_socket_get_local_address (NULL, &error) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_get_remote_address (NULL, &error) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_is_connected (NULL) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (NULL) == TRUE);
+
+ P_TEST_CHECK (p_socket_check_connect_result (NULL, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ p_socket_set_keepalive (NULL, FALSE);
+ p_socket_set_blocking (NULL, FALSE);
+ p_socket_set_timeout (NULL, 0);
+ p_socket_set_listen_backlog (NULL, 0);
+
+ P_TEST_CHECK (p_socket_bind (NULL, NULL, FALSE, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_connect (NULL, NULL, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_listen (NULL, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_accept (NULL, &error) == NULL);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_receive (NULL, NULL, 0, &error) == -1);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_receive_from (NULL, NULL, NULL, 0, &error) == -1);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_send (NULL, NULL, 0, &error) == -1);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_send_to (NULL, NULL, NULL, 0, &error) == -1);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_close (NULL, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_shutdown (NULL, FALSE, FALSE, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_set_buffer_size (NULL, P_SOCKET_DIRECTION_RCV, 0, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ P_TEST_CHECK (p_socket_set_buffer_size (NULL, P_SOCKET_DIRECTION_SND, 0, &error) == FALSE);
+ P_TEST_CHECK (error != NULL);
+ clean_error (&error);
+
+ p_socket_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_general_udp_test)
+{
+ p_libsys_init ();
+
+ /* Test UDP socket */
+ PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_DATAGRAM,
+ P_SOCKET_PROTOCOL_UDP,
+ NULL);
+
+ P_TEST_CHECK (socket != NULL);
+ P_TEST_CHECK (p_socket_get_family (socket) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_get_fd (socket) >= 0);
+ P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 5);
+ P_TEST_CHECK (p_socket_get_timeout (socket) == 0);
+
+ /* On some operating systems (i.e. OpenVMS) remote address is not NULL */
+ PSocketAddress *remote_addr = p_socket_get_remote_address (socket, NULL);
+
+ if (remote_addr != NULL) {
+ P_TEST_CHECK (p_socket_address_is_any (remote_addr) == TRUE);
+ p_socket_address_free (remote_addr);
+ remote_addr = NULL;
+ }
+
+ P_TEST_CHECK (p_socket_get_protocol (socket) == P_SOCKET_PROTOCOL_UDP);
+ P_TEST_CHECK (p_socket_get_blocking (socket) == TRUE);
+ P_TEST_CHECK (p_socket_get_type (socket) == P_SOCKET_TYPE_DATAGRAM);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (socket) == FALSE);
+
+ p_socket_set_listen_backlog (socket, 12);
+ p_socket_set_timeout (socket, -10);
+ P_TEST_CHECK (p_socket_get_timeout (socket) == 0);
+ p_socket_set_timeout (socket, 10);
+
+ P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 12);
+ P_TEST_CHECK (p_socket_get_timeout (socket) == 10);
+
+ PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 32111);
+ P_TEST_CHECK (sock_addr != NULL);
+
+ P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE);
+
+ /* Test creating socket from descriptor */
+ PSocket *fd_socket = p_socket_new_from_fd (p_socket_get_fd (socket), NULL);
+ P_TEST_CHECK (fd_socket != NULL);
+ P_TEST_CHECK (p_socket_get_family (fd_socket) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_get_fd (fd_socket) >= 0);
+ P_TEST_CHECK (p_socket_get_listen_backlog (fd_socket) == 5);
+ P_TEST_CHECK (p_socket_get_timeout (fd_socket) == 0);
+
+ remote_addr = p_socket_get_remote_address (fd_socket, NULL);
+
+ if (remote_addr != NULL) {
+ P_TEST_CHECK (p_socket_address_is_any (remote_addr) == TRUE);
+ p_socket_address_free (remote_addr);
+ remote_addr = NULL;
+ }
+
+ P_TEST_CHECK (p_socket_get_protocol (fd_socket) == P_SOCKET_PROTOCOL_UDP);
+ P_TEST_CHECK (p_socket_get_blocking (fd_socket) == TRUE);
+ P_TEST_CHECK (p_socket_get_type (fd_socket) == P_SOCKET_TYPE_DATAGRAM);
+ P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (fd_socket) == FALSE);
+
+ p_socket_set_keepalive (fd_socket, FALSE);
+ P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE);
+
+ p_socket_set_keepalive (fd_socket, TRUE);
+ p_socket_set_keepalive (fd_socket, FALSE);
+ P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE);
+
+ /* Test UDP local address */
+ PSocketAddress *addr = p_socket_get_local_address (socket, NULL);
+ P_TEST_CHECK (addr != NULL);
+
+ P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE);
+
+ p_socket_address_free (sock_addr);
+ p_socket_address_free (addr);
+
+ /* Test UDP connecting to remote address */
+ p_socket_set_timeout (socket, 1000);
+ addr = p_socket_address_new ("127.0.0.1", 32115);
+ P_TEST_CHECK (addr != NULL);
+ P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == TRUE);
+
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == TRUE);
+
+ sock_addr = p_socket_get_remote_address (socket, NULL);
+
+ /* Syllable doesn't support getpeername() for UDP sockets */
+#ifdef P_OS_SYLLABLE
+ P_TEST_CHECK (sock_addr == NULL);
+ sock_addr = p_socket_address_new ("127.0.0.1", 32115);
+ P_TEST_CHECK (addr != NULL);
+#else
+ P_TEST_CHECK (sock_addr != NULL);
+ P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE);
+#endif
+
+ /* Not supported on Syllable */
+#ifndef P_OS_SYLLABLE
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == TRUE);
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == TRUE);
+ P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == TRUE);
+#endif
+
+ P_TEST_CHECK (p_socket_is_connected (socket) == TRUE);
+ P_TEST_CHECK (p_socket_close (socket, NULL) == TRUE);
+
+ pchar sock_buf[10];
+
+ P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_listen (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_accept (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_receive (socket, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_receive_from (socket, NULL, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_send (socket, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_send_to (socket, addr, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_shutdown (socket, TRUE, TRUE, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL);
+ P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_get_fd (socket) == -1);
+ P_TEST_CHECK (p_socket_is_connected (socket) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (socket) == TRUE);
+
+ p_socket_set_keepalive (socket, TRUE);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE);
+
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == FALSE);
+
+ p_socket_address_free (sock_addr);
+ p_socket_address_free (addr);
+ p_socket_free (socket);
+ p_socket_free (fd_socket);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_general_tcp_test)
+{
+ p_libsys_init ();
+
+ /* Test TCP socket */
+ PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET,
+ P_SOCKET_TYPE_STREAM,
+ P_SOCKET_PROTOCOL_TCP,
+ NULL);
+ p_socket_set_blocking (socket, FALSE);
+ p_socket_set_listen_backlog (socket, 11);
+
+ p_socket_set_timeout (socket, -12);
+ P_TEST_CHECK (p_socket_get_timeout (socket) == 0);
+ p_socket_set_timeout (socket, 12);
+
+ P_TEST_CHECK (socket != NULL);
+ P_TEST_CHECK (p_socket_get_family (socket) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_get_fd (socket) >= 0);
+ P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 11);
+ P_TEST_CHECK (p_socket_get_timeout (socket) == 12);
+ P_TEST_CHECK (p_socket_get_remote_address (socket, NULL) == NULL);
+ P_TEST_CHECK (p_socket_get_protocol (socket) == P_SOCKET_PROTOCOL_TCP);
+ P_TEST_CHECK (p_socket_get_blocking (socket) == FALSE);
+ P_TEST_CHECK (p_socket_get_type (socket) == P_SOCKET_TYPE_STREAM);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (socket) == FALSE);
+
+ p_socket_set_keepalive (socket, FALSE);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+
+ p_socket_set_keepalive (socket, TRUE);
+ p_socket_set_keepalive (socket, FALSE);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+
+ PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 0);
+ P_TEST_CHECK (sock_addr != NULL);
+
+ P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE);
+
+ PSocketAddress *addr = p_socket_get_local_address (socket, NULL);
+ P_TEST_CHECK (addr != NULL);
+
+ P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE);
+
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == TRUE);
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == TRUE);
+
+ /* In case of success p_socket_check_connect_result() marks socket as connected */
+ P_TEST_CHECK (p_socket_is_connected (socket) == FALSE);
+ P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == TRUE);
+ P_TEST_CHECK (p_socket_close (socket, NULL) == TRUE);
+
+ pchar sock_buf[10];
+
+ P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_listen (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_accept (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_receive (socket, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_receive_from (socket, NULL, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_send (socket, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_send_to (socket, addr, sock_buf, sizeof (sock_buf), NULL) == -1);
+ P_TEST_CHECK (p_socket_shutdown (socket, TRUE, TRUE, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL);
+ P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_is_closed (socket) == TRUE);
+ P_TEST_CHECK (p_socket_get_fd (socket) == -1);
+
+ p_socket_set_keepalive (socket, TRUE);
+ P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE);
+
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE);
+
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == FALSE);
+ P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == FALSE);
+
+ p_socket_address_free (sock_addr);
+ p_socket_address_free (addr);
+
+ p_socket_free (socket);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_udp_test)
+{
+ p_libsys_init ();
+
+ is_sender_working = TRUE;
+ is_receiver_working = TRUE;
+
+ SocketTestData data;
+ data.receiver_port = 0;
+ data.sender_port = 0;
+ data.shutdown_channel = FALSE;
+
+ PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) udp_socket_receiver_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ PUThread *sender_thr = p_uthread_create ((PUThreadFunc) udp_socket_sender_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ P_TEST_CHECK (sender_thr != NULL);
+ P_TEST_CHECK (receiver_thr != NULL);
+
+ p_uthread_sleep (8000);
+
+ is_sender_working = FALSE;
+ pint send_counter = p_uthread_join (sender_thr);
+
+ p_uthread_sleep (2000);
+
+ is_receiver_working = FALSE;
+ pint recv_counter = p_uthread_join (receiver_thr);
+
+ P_TEST_CHECK (send_counter > 0);
+ P_TEST_CHECK (recv_counter > 0);
+
+ p_uthread_unref (sender_thr);
+ p_uthread_unref (receiver_thr);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_tcp_test)
+{
+ p_libsys_init ();
+
+ is_sender_working = TRUE;
+ is_receiver_working = TRUE;
+
+ SocketTestData data;
+ data.receiver_port = 0;
+ data.sender_port = 0;
+ data.shutdown_channel = FALSE;
+
+ PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) tcp_socket_receiver_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ PUThread *sender_thr = p_uthread_create ((PUThreadFunc) tcp_socket_sender_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ P_TEST_CHECK (receiver_thr != NULL);
+ P_TEST_CHECK (sender_thr != NULL);
+
+ p_uthread_sleep (8000);
+
+ is_sender_working = FALSE;
+ pint send_counter = p_uthread_join (sender_thr);
+
+ p_uthread_sleep (2000);
+
+ is_receiver_working = FALSE;
+ pint recv_counter = p_uthread_join (receiver_thr);
+
+ P_TEST_CHECK (send_counter > 0);
+ P_TEST_CHECK (recv_counter > 0);
+
+ p_uthread_unref (sender_thr);
+ p_uthread_unref (receiver_thr);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocket_shutdown_test)
+{
+ p_libsys_init ();
+
+ is_sender_working = TRUE;
+ is_receiver_working = TRUE;
+
+ SocketTestData data;
+ data.receiver_port = 0;
+ data.sender_port = 0;
+ data.shutdown_channel = TRUE;
+
+ PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) tcp_socket_receiver_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ PUThread *sender_thr = p_uthread_create ((PUThreadFunc) tcp_socket_sender_thread,
+ (ppointer) &data,
+ TRUE,
+ NULL);
+
+ P_TEST_CHECK (receiver_thr != NULL);
+ P_TEST_CHECK (sender_thr != NULL);
+
+ p_uthread_sleep (8000);
+
+ is_sender_working = FALSE;
+ pint send_counter = p_uthread_join (sender_thr);
+
+ p_uthread_sleep (2000);
+
+ is_receiver_working = FALSE;
+ pint recv_counter = p_uthread_join (receiver_thr);
+
+ P_TEST_CHECK (send_counter == 0);
+ P_TEST_CHECK (recv_counter == 0);
+
+ p_uthread_unref (sender_thr);
+ p_uthread_unref (receiver_thr);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (psocket_nomem_test);
+ P_TEST_SUITE_RUN_CASE (psocket_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (psocket_general_udp_test);
+ P_TEST_SUITE_RUN_CASE (psocket_general_tcp_test);
+ P_TEST_SUITE_RUN_CASE (psocket_udp_test);
+ P_TEST_SUITE_RUN_CASE (psocket_tcp_test);
+ P_TEST_SUITE_RUN_CASE (psocket_shutdown_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/psocketaddress_test.cpp b/3rdparty/plibsys/tests/psocketaddress_test.cpp
new file mode 100644
index 0000000..2085725
--- /dev/null
+++ b/3rdparty/plibsys/tests/psocketaddress_test.cpp
@@ -0,0 +1,338 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+
+P_TEST_MODULE_INIT ();
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (psocketaddress_nomem_test)
+{
+ p_libsys_init ();
+
+ PSocketAddress *sock_addr = p_socket_address_new ("192.168.0.1", 1058);
+ P_TEST_CHECK (sock_addr != NULL);
+
+ psize native_size = p_socket_address_get_native_size (sock_addr);
+ P_TEST_CHECK (native_size > 0);
+
+ ppointer addr_buf = p_malloc0 (native_size);
+ P_TEST_CHECK (addr_buf != NULL);
+
+ P_TEST_CHECK (p_socket_address_to_native (sock_addr, addr_buf, native_size - 1) == FALSE);
+ P_TEST_CHECK (p_socket_address_to_native (sock_addr, addr_buf, native_size) == TRUE);
+ p_socket_address_free (sock_addr);
+
+ PSocketAddress *sock_addr6;
+ psize native_size6;
+ ppointer addr_buf6;
+
+ if (p_socket_address_is_ipv6_supported ()) {
+ sock_addr6 = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 1058);
+ P_TEST_CHECK (sock_addr6 != NULL);
+
+ native_size6 = p_socket_address_get_native_size (sock_addr6);
+ P_TEST_CHECK (native_size6 > 0);
+
+ addr_buf6 = p_malloc0 (native_size6);
+ P_TEST_CHECK (addr_buf6 != NULL);
+
+ P_TEST_CHECK (p_socket_address_to_native (sock_addr6, addr_buf6, native_size6 - 1) == FALSE);
+ P_TEST_CHECK (p_socket_address_to_native (sock_addr6, addr_buf6, native_size6) == TRUE);
+ p_socket_address_free (sock_addr6);
+ }
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_socket_address_new ("192.168.0.1", 1058) == NULL);
+ P_TEST_CHECK (p_socket_address_new_any (P_SOCKET_FAMILY_INET, 1058) == NULL);
+ P_TEST_CHECK (p_socket_address_new_loopback (P_SOCKET_FAMILY_INET, 1058) == NULL);
+ P_TEST_CHECK (p_socket_address_new_from_native (addr_buf, native_size) == NULL);
+
+ if (p_socket_address_is_ipv6_supported ())
+ P_TEST_CHECK (p_socket_address_new_from_native (addr_buf6, native_size6) == NULL);
+
+ p_mem_restore_vtable ();
+
+ P_TEST_CHECK (p_socket_address_new_from_native (addr_buf, native_size - 1) == NULL);
+
+ if (p_socket_address_is_ipv6_supported ()) {
+ P_TEST_CHECK (p_socket_address_new_from_native (addr_buf6, native_size6 - 1) == NULL);
+ p_free (addr_buf6);
+ }
+
+ p_free (addr_buf);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocketaddress_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_socket_address_new_from_native (NULL, 0) == NULL);
+ P_TEST_CHECK (p_socket_address_new (NULL, 0) == NULL);
+ P_TEST_CHECK (p_socket_address_new ("bad_address", 0) == NULL);
+ P_TEST_CHECK (p_socket_address_new_any (P_SOCKET_FAMILY_UNKNOWN, 0) == NULL);
+ P_TEST_CHECK (p_socket_address_new_loopback (P_SOCKET_FAMILY_UNKNOWN, 0) == NULL);
+ P_TEST_CHECK (p_socket_address_to_native (NULL, NULL, 0) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_native_size (NULL) == 0);
+ P_TEST_CHECK (p_socket_address_get_family (NULL) == P_SOCKET_FAMILY_UNKNOWN);
+ P_TEST_CHECK (p_socket_address_get_address (NULL) == NULL);
+ P_TEST_CHECK (p_socket_address_get_port (NULL) == 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (NULL) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (NULL) == 0);
+ P_TEST_CHECK (p_socket_address_is_any (NULL) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_loopback (NULL) == FALSE);
+
+ p_socket_address_set_flow_info (NULL, 0);
+ p_socket_address_set_scope_id (NULL, 0);
+ p_socket_address_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (psocketaddress_general_test)
+{
+ p_libsys_init ();
+
+ /* Test IPv4 LAN address */
+ PSocketAddress *addr = p_socket_address_new ("192.168.0.1", 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ pchar *addr_str = p_socket_address_get_address (addr);
+
+ P_TEST_REQUIRE (addr_str != NULL);
+ P_TEST_CHECK (strcmp (addr_str, "192.168.0.1") == 0);
+
+ p_free (addr_str);
+ p_socket_address_free (addr);
+
+ if (p_socket_address_is_ipv6_supported ()) {
+ /* Test IPv6 LAN address */
+ addr = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ addr_str = p_socket_address_get_address (addr);
+
+ P_TEST_REQUIRE (addr_str != NULL);
+ P_TEST_CHECK (strcmp (addr_str, "2001:cdba:345f:24ab:fe45:5423:3257:9652") == 0);
+
+ p_free (addr_str);
+ p_socket_address_free (addr);
+ }
+
+ /* Test IPv4 loopback address */
+ addr = p_socket_address_new_loopback (P_SOCKET_FAMILY_INET, 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == TRUE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ p_socket_address_free (addr);
+
+ if (p_socket_address_is_ipv6_supported ()) {
+ /* Test IPv6 loopback address */
+ addr = p_socket_address_new_loopback (P_SOCKET_FAMILY_INET6, 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == TRUE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ p_socket_address_free (addr);
+ }
+
+ /* Test IPv4 any interface */
+ addr = p_socket_address_new_any (P_SOCKET_FAMILY_INET, 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == TRUE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ psize native_size = p_socket_address_get_native_size (addr);
+
+ p_socket_address_free (addr);
+
+ /* Test IPv4 native raw data */
+ ppointer native_buf = p_malloc0 (native_size);
+ P_TEST_CHECK (native_buf != NULL);
+ P_TEST_CHECK (p_socket_address_new_from_native (native_buf, native_size) == NULL);
+ addr = p_socket_address_new ("192.168.0.2", 2345);
+ P_TEST_REQUIRE (addr != NULL);
+
+ p_socket_address_set_flow_info (addr, 1);
+ p_socket_address_set_scope_id (addr, 1);
+
+ P_TEST_CHECK (p_socket_address_to_native (addr, native_buf, native_size) == TRUE);
+ p_socket_address_free (addr);
+
+ addr = p_socket_address_new_from_native (native_buf, native_size);
+
+ P_TEST_CHECK (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) == native_size);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ addr_str = p_socket_address_get_address (addr);
+
+ P_TEST_REQUIRE (addr_str != NULL);
+ P_TEST_CHECK (strcmp (addr_str, "192.168.0.2") == 0);
+
+ p_free (native_buf);
+ p_free (addr_str);
+ p_socket_address_free (addr);
+
+ if (p_socket_address_is_ipv6_supported ()) {
+ /* Test IPv6 any interface */
+ addr = p_socket_address_new_any (P_SOCKET_FAMILY_INET6, 2345);
+
+ P_TEST_REQUIRE (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == TRUE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0);
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0);
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0);
+
+ native_size = p_socket_address_get_native_size (addr);
+
+ p_socket_address_free (addr);
+
+ /* Test IPv6 native raw data */
+ native_buf = p_malloc0 (native_size);
+ P_TEST_CHECK (native_buf != NULL);
+ P_TEST_CHECK (p_socket_address_new_from_native (native_buf, native_size) == NULL);
+ addr = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 2345);
+ P_TEST_REQUIRE (addr != NULL);
+
+ p_socket_address_set_flow_info (addr, 1);
+ p_socket_address_set_scope_id (addr, 1);
+
+ P_TEST_CHECK (p_socket_address_to_native (addr, native_buf, native_size) == TRUE);
+ p_socket_address_free (addr);
+
+ addr = p_socket_address_new_from_native (native_buf, native_size);
+
+ P_TEST_CHECK (addr != NULL);
+ P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE);
+ P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6);
+ P_TEST_CHECK (p_socket_address_get_port (addr) == 2345);
+ P_TEST_CHECK (p_socket_address_get_native_size (addr) == native_size);
+
+ if (p_socket_address_is_flow_info_supported ())
+ P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 1);
+
+ if (p_socket_address_is_scope_id_supported ())
+ P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 1);
+
+ addr_str = p_socket_address_get_address (addr);
+
+ P_TEST_REQUIRE (addr_str != NULL);
+ P_TEST_CHECK (strcmp (addr_str, "2001:cdba:345f:24ab:fe45:5423:3257:9652") == 0);
+
+ p_free (native_buf);
+ p_free (addr_str);
+ p_socket_address_free (addr);
+ }
+
+ if (p_socket_address_is_flow_info_supported () || p_socket_address_is_scope_id_supported ())
+ P_TEST_CHECK (p_socket_address_is_ipv6_supported () == TRUE);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (psocketaddress_nomem_test);
+ P_TEST_SUITE_RUN_CASE (psocketaddress_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (psocketaddress_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pspinlock_test.cpp b/3rdparty/plibsys/tests/pspinlock_test.cpp
new file mode 100644
index 0000000..1f23dab
--- /dev/null
+++ b/3rdparty/plibsys/tests/pspinlock_test.cpp
@@ -0,0 +1,148 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2016-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+#define PSPINLOCK_MAX_VAL 10
+
+static pint spinlock_test_val = 0;
+static PSpinLock * global_spinlock = NULL;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static void * spinlock_test_thread (void *)
+{
+ pint i;
+
+ for (i = 0; i < 1000; ++i) {
+ if (!p_spinlock_trylock (global_spinlock)) {
+ if (!p_spinlock_lock (global_spinlock))
+ p_uthread_exit (1);
+ }
+
+ if (spinlock_test_val == PSPINLOCK_MAX_VAL)
+ --spinlock_test_val;
+ else {
+ p_uthread_sleep (1);
+ ++spinlock_test_val;
+ }
+
+ if (!p_spinlock_unlock (global_spinlock))
+ p_uthread_exit (1);
+ }
+
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (pspinlock_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+ P_TEST_CHECK (p_spinlock_new () == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pspinlock_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_REQUIRE (p_spinlock_lock (NULL) == FALSE);
+ P_TEST_REQUIRE (p_spinlock_unlock (NULL) == FALSE);
+ P_TEST_REQUIRE (p_spinlock_trylock (NULL) == FALSE);
+ p_spinlock_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pspinlock_general_test)
+{
+ PUThread *thr1, *thr2;
+
+ p_libsys_init ();
+
+ spinlock_test_val = PSPINLOCK_MAX_VAL;
+ global_spinlock = p_spinlock_new ();
+
+ P_TEST_REQUIRE (global_spinlock != NULL);
+
+ thr1 = p_uthread_create ((PUThreadFunc) spinlock_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) spinlock_test_thread, NULL, TRUE, NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ P_TEST_CHECK (p_uthread_join (thr1) == 0);
+ P_TEST_CHECK (p_uthread_join (thr2) == 0);
+
+ P_TEST_REQUIRE (spinlock_test_val == PSPINLOCK_MAX_VAL);
+
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+ p_spinlock_free (global_spinlock);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pspinlock_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pspinlock_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (pspinlock_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pstdarg_test.cpp b/3rdparty/plibsys/tests/pstdarg_test.cpp
new file mode 100644
index 0000000..7df041f
--- /dev/null
+++ b/3rdparty/plibsys/tests/pstdarg_test.cpp
@@ -0,0 +1,205 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Jean-Damien Durand <jeandamiendurand@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#if defined(P_CC_WATCOM)
+# pragma disable_message (7)
+#endif
+
+P_TEST_MODULE_INIT ();
+
+static void variadic_function (pint unused, ...);
+static void variadic_function_copy_all (pint unused, p_va_list ap);
+static void variadic_function_copy_trail (pint unused, p_va_list ap);
+
+/* The "runtime" thingies here are just to avoid compiler warnings */
+/* In head, In trail */
+static const pint8 pint8_var[2] = { P_MININT8, P_MAXINT8 };
+static const puint8 puint8_var[2] = { 0, P_MAXUINT8 };
+static const pint16 pint16_var[2] = { P_MININT16, P_MAXINT16 };
+static const puint16 puint16_var[2] = { 0, P_MAXUINT16 };
+static pint32 pint32_var[2] = { 0 /* runtime */, 0 /* runtime */ };
+static puint32 puint32_var[2] = { 0, 0 /* runtime */ };
+static pint64 pint64_var[2] = { 0 /* runtime */, 0 /* runtime */ };
+static puint64 puint64_var[2] = { 0, 0 /* runtime */ };
+static const pint pint_var[2] = { P_MININT, P_MAXINT };
+static const puint puint_var[2] = { 0, P_MAXUINT };
+static const pshort pshort_var[2] = { P_MINSHORT, P_MAXSHORT };
+static const plong plong_var[2] = { P_MINLONG, P_MAXLONG };
+static const pchar pchar_var[2] = { '\0', 'z' };
+static const ppointer ppointer_var[2] = { NULL, (ppointer) p_libsys_init };
+static const pfloat pfloat_var[2] = { -1.234f, 1.234f };
+static const pdouble pdouble_var[2] = { -1.567, 1.567 };
+
+/* Macros are used for testing because these tests MUST play with the CURRENT stack. */
+
+#define P_TEST_VA_ARG(ap, type, wantedvalue) do { \
+ P_DEBUG ("Unstacking a " #type); \
+ P_TEST_CHECK (type##_va_arg(ap) == wantedvalue); \
+ } while (0)
+
+#define P_TEST_VA_ARG_HEAD(ap) do { \
+ P_TEST_VA_ARG(ap, pint8, pint8_var[0]); \
+ P_TEST_VA_ARG(ap, puint8, puint8_var[0]); \
+ P_TEST_VA_ARG(ap, pint16, pint16_var[0]); \
+ P_TEST_VA_ARG(ap, puint16, puint16_var[0]); \
+ P_TEST_VA_ARG(ap, pint32, pint32_var[0]); \
+ P_TEST_VA_ARG(ap, puint32, puint32_var[0]); \
+ P_TEST_VA_ARG(ap, pint64, pint64_var[0]); \
+ P_TEST_VA_ARG(ap, puint64, puint64_var[0]); \
+ P_TEST_VA_ARG(ap, pint, pint_var[0]); \
+ P_TEST_VA_ARG(ap, puint, puint_var[0]); \
+ P_TEST_VA_ARG(ap, pshort, pshort_var[0]); \
+ P_TEST_VA_ARG(ap, plong, plong_var[0]); \
+ P_TEST_VA_ARG(ap, pchar, pchar_var[0]); \
+ P_TEST_VA_ARG(ap, ppointer, ppointer_var[0]); \
+ P_TEST_VA_ARG(ap, pfloat, pfloat_var[0]); \
+ P_TEST_VA_ARG(ap, pdouble, pdouble_var[0]); \
+ } while (0)
+
+#define P_TEST_VA_ARG_TRAIL(ap) do { \
+ P_TEST_VA_ARG(ap, pdouble, pdouble_var[1]); \
+ P_TEST_VA_ARG(ap, pfloat, pfloat_var[1]); \
+ P_TEST_VA_ARG(ap, ppointer, ppointer_var[1]); \
+ P_TEST_VA_ARG(ap, pchar, pchar_var[1]); \
+ P_TEST_VA_ARG(ap, plong, plong_var[1]); \
+ P_TEST_VA_ARG(ap, pshort, pshort_var[1]); \
+ P_TEST_VA_ARG(ap, puint, puint_var[1]); \
+ P_TEST_VA_ARG(ap, pint, pint_var[1]); \
+ P_TEST_VA_ARG(ap, puint64, puint64_var[1]); \
+ P_TEST_VA_ARG(ap, pint64, pint64_var[1]); \
+ P_TEST_VA_ARG(ap, puint32, puint32_var[1]); \
+ P_TEST_VA_ARG(ap, pint32, pint32_var[1]); \
+ P_TEST_VA_ARG(ap, puint16, puint16_var[1]); \
+ P_TEST_VA_ARG(ap, pint16, pint16_var[1]); \
+ P_TEST_VA_ARG(ap, puint8, puint8_var[1]); \
+ P_TEST_VA_ARG(ap, pint8, pint8_var[1]); \
+ } while (0)
+
+static void variadic_function_copy_all (pint unused, p_va_list ap)
+{
+ P_UNUSED (unused);
+ P_DEBUG ("Unstacking a copy of all the arguments");
+ P_TEST_VA_ARG_HEAD (ap);
+ P_TEST_VA_ARG_TRAIL (ap);
+}
+
+static void variadic_function_copy_trail (pint unused, p_va_list ap)
+{
+ P_UNUSED (unused);
+ P_DEBUG ("Unstacking second part of the arguments");
+ P_TEST_VA_ARG_TRAIL (ap);
+}
+
+static void variadic_function (pint unused, ...)
+{
+ p_va_list ap;
+ p_va_list ap2;
+
+ p_va_start (ap, unused);
+
+ P_DEBUG ("Copy of arguments");
+ p_va_copy (ap2, ap);
+ variadic_function_copy_all (unused, ap2);
+ p_va_end (ap2);
+
+ P_DEBUG ("Unstacking first part of arguments");
+ P_TEST_VA_ARG_HEAD (ap);
+
+ P_DEBUG ("Copy of arguments at current unstack state, i.e. in the middle");
+ p_va_copy (ap2, ap);
+ variadic_function_copy_trail (unused, ap2);
+ p_va_end (ap2);
+
+ P_DEBUG ("Unstacking second part of arguments");
+ P_TEST_VA_ARG_TRAIL (ap);
+
+ p_va_end (ap);
+}
+
+P_TEST_CASE_BEGIN (pstdarg_general_test)
+{
+ p_libsys_init ();
+
+ pint32_var[0] = P_MININT16;
+ pint32_var[0] <<= 16;
+ pint32_var[1] = P_MAXINT16;
+ pint32_var[1] <<= 16;
+ puint32_var[1] = P_MAXUINT16;
+ puint32_var[1] <<= 16;
+
+ pint64_var[0] = pint32_var[0];
+ pint64_var[0] <<= 32;
+ pint64_var[1] = pint32_var[1];
+ pint64_var[1] <<= 32;
+ puint64_var[1] = puint32_var[1];
+ puint64_var[1] <<= 32;
+
+ variadic_function (0,
+ pint8_var[0],
+ puint8_var[0],
+ pint16_var[0],
+ puint16_var[0],
+ pint32_var[0],
+ puint32_var[0],
+ pint64_var[0],
+ puint64_var[0],
+ pint_var[0],
+ puint_var[0],
+ pshort_var[0],
+ plong_var[0],
+ pchar_var[0],
+ ppointer_var[0],
+ pfloat_var[0],
+ pdouble_var[0],
+ /* Cut is here when testing p_va_copy, we stack in reverse order */
+ pdouble_var[1],
+ pfloat_var[1],
+ ppointer_var[1],
+ pchar_var[1],
+ plong_var[1],
+ pshort_var[1],
+ puint_var[1],
+ pint_var[1],
+ puint64_var[1],
+ pint64_var[1],
+ puint32_var[1],
+ pint32_var[1],
+ puint16_var[1],
+ pint16_var[1],
+ puint8_var[1],
+ pint8_var[1]);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pstdarg_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/pstring_test.cpp b/3rdparty/plibsys/tests/pstring_test.cpp
new file mode 100644
index 0000000..73e5805
--- /dev/null
+++ b/3rdparty/plibsys/tests/pstring_test.cpp
@@ -0,0 +1,289 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <string.h>
+#include <float.h>
+#include <math.h>
+
+P_TEST_MODULE_INIT ();
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (pstring_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_strdup ("test string") == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pstring_strdup_test)
+{
+ p_libsys_init ();
+
+ const pchar *test_str_1 = "Test string";
+
+ pchar *new_string = p_strdup (test_str_1);
+ P_TEST_CHECK (new_string != NULL);
+ p_free (new_string);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pstring_strchomp_test)
+{
+ p_libsys_init ();
+
+ const pchar *test_chomp_str_orig = "Test chomp string";
+ const pchar *test_chomp_str_1 = "Test chomp string ";
+ const pchar *test_chomp_str_2 = "\n\nTest chomp string ";
+ const pchar *test_chomp_str_3 = "\n\rTest chomp string \n";
+ const pchar *test_chomp_str_4 = "Test chomp string\n\n";
+ const pchar *test_chomp_str_5 = " \rTest chomp string \n\n ";
+ const pchar *test_chomp_str_6 = " \rI\n\n ";
+ const pchar *test_chomp_str_7 = "\n";
+ const pchar *test_chomp_str_8 = "I";
+ const pchar *test_chomp_str_9 = "";
+ const pchar *test_chomp_str_10 = " ";
+ const pchar *test_chomp_str_11 = NULL;
+
+ pchar *new_string = p_strchomp (test_chomp_str_1);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_2);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_3);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_4);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_5);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_6);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp ("I", new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_7);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (*new_string == '\0');
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_8);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (strcmp ("I", new_string) == 0);
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_9);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (*new_string == '\0');
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_10);
+ P_TEST_REQUIRE (new_string != NULL);
+ P_TEST_CHECK (*new_string == '\0');
+ p_free (new_string);
+
+ new_string = p_strchomp (test_chomp_str_11);
+ P_TEST_CHECK (new_string == NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pstring_strtok_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_strtok (NULL, NULL, NULL) == NULL);
+
+ /* First string */
+ pchar test_string[] = "1,2,3";
+ pchar *token, *next_token;
+
+ /* Check third parameter for possible NULL */
+ token = p_strtok (test_string, ",", NULL);
+
+ if (strcmp (token, "1") != 0) {
+ token = p_strtok (test_string, ",", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "1") == 0);
+ }
+
+ token = p_strtok (NULL, ",", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "2") == 0);
+
+ token = p_strtok (NULL, ",", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "3") == 0);
+
+ token = p_strtok (NULL, ",", &next_token);
+ P_TEST_CHECK (token == NULL);
+
+ /* Second string */
+ pchar test_string_2[] = "Test string, to test";
+
+ token = p_strtok (test_string_2, " ", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "Test") == 0);
+
+ token = p_strtok (NULL, ", ", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "string") == 0);
+
+ token = p_strtok (NULL, ", ", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "to") == 0);
+
+ token = p_strtok (NULL, ", \t\n", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "test") == 0);
+
+ token = p_strtok (NULL, ", \t\n", &next_token);
+ P_TEST_CHECK (token == NULL);
+
+ /* Third string */
+ pchar test_string_3[] = "compile\ttest\ndeploy";
+
+ token = p_strtok (test_string_3, "\t\n", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "compile") == 0);
+
+ token = p_strtok (NULL, "\t\n", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "test") == 0);
+
+ token = p_strtok (NULL, "\t\n", &next_token);
+ P_TEST_CHECK (token != NULL);
+ P_TEST_CHECK (strcmp (token, "deploy") == 0);
+
+ token = p_strtok (NULL, ", \t\n", &next_token);
+ P_TEST_CHECK (token == NULL);
+
+ /* Fourth string */
+ pchar test_string_4[] = "\t \t\n \t";
+
+ token = p_strtok (test_string_4, "\t\n ", &next_token);
+ P_TEST_CHECK (token == NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (pstring_strtod_test)
+{
+ p_libsys_init ();
+
+ /* Incorrect input */
+ P_TEST_CHECK_CLOSE (p_strtod (NULL), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("e2"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("e-2"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-e2"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-e-2"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("0,3"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("12,3"), 12.0, 0.0001);
+
+ /* Correct input */
+ P_TEST_CHECK_CLOSE (p_strtod ("0"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("0.0"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-0"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-0.0"), 0.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("3.14"), 3.14, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("+3.14"), 3.14, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-12.256"), -12.256, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("0.056"), 0.056, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-0.057"), -0.057, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("1.5423e2"), 154.23, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("1e3"), 1000.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("1e+3"), 1000.0, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-2.56e1"), -25.6, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("-2.56e+1"), -25.6, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("123e-2"), 1.23, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("3.14e-1"), 0.314, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("3.14e60"), 3.14e60, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("3.14e-60"), 3.14e-60, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("2.14e10"), 2.14e10, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("2.14e-10"), 2.14e-10, 0.0001);
+ P_TEST_CHECK_CLOSE (p_strtod ("1.10e310"), 1.10e308, 0.0001);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (pstring_nomem_test);
+ P_TEST_SUITE_RUN_CASE (pstring_strdup_test);
+ P_TEST_SUITE_RUN_CASE (pstring_strchomp_test);
+ P_TEST_SUITE_RUN_CASE (pstring_strtok_test);
+ P_TEST_SUITE_RUN_CASE (pstring_strtod_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/ptestmacros.h b/3rdparty/plibsys/tests/ptestmacros.h
new file mode 100644
index 0000000..206a8a6
--- /dev/null
+++ b/3rdparty/plibsys/tests/ptestmacros.h
@@ -0,0 +1,131 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file ptestmacros.h
+ * @brief Macros for unit-tests
+ * @author Alexander Saprykin
+ */
+
+#ifndef PLIBSYS_HEADER_PTESTMACROS_H
+#define PLIBSYS_HEADER_PTESTMACROS_H
+
+#include <stdlib.h>
+
+#include <plibsys.h>
+
+#if defined (P_CC_MSVC)
+# pragma warning (push)
+# pragma warning (disable : 4723)
+#elif defined (P_CC_BORLAND)
+# pragma option -w-8008
+# pragma option -w-8066
+#elif defined (P_CC_WATCOM)
+# pragma disable_message (13)
+# pragma disable_message (367)
+# pragma disable_message (368)
+#endif
+
+inline double p_test_safe_division (double f1, double f2)
+{
+ return (f2 < 1.0 && f1 > f2 * P_MAXDOUBLE) ? P_MAXDOUBLE :
+ (((f2 > 1.0 && f1 < f2 * P_MINDOUBLE) || f1 == 0) ? 0 : f1 / f2);
+}
+
+#ifdef P_CC_MSVC
+# pragma warning (pop)
+#endif
+
+#define P_TEST_MODULE_FAIL_COUNTER p_test_module_fail_counter
+#define P_TEST_SUITE_FAIL_COUNTER p_test_suite_fail_counter
+
+#define P_TEST_MODULE_INIT() static pint P_TEST_MODULE_FAIL_COUNTER = 0
+
+#define P_TEST_CASE_BEGIN(test_case_name) \
+ pint p_test_case_##test_case_name (void) \
+ { \
+ P_TEST_MODULE_FAIL_COUNTER = 0;
+
+#define P_TEST_CASE_END() \
+ return (P_TEST_MODULE_FAIL_COUNTER == 0) ? 0 : -1; \
+ }
+
+#define P_TEST_CASE_RETURN() return 0
+
+#define P_TEST_SUITE_BEGIN() \
+ int main (void) \
+ { \
+ pint P_TEST_SUITE_FAIL_COUNTER = 0;
+
+#define P_TEST_SUITE_ARGS_BEGIN() \
+ int main (int argc, char *argv[]) \
+ { \
+ pint P_TEST_SUITE_FAIL_COUNTER = 0;
+
+#define P_TEST_SUITE_END() \
+ if (P_TEST_SUITE_FAIL_COUNTER == 0) \
+ printf ("Test passed\n"); \
+ else \
+ printf ("Test failed\n"); \
+ \
+ return P_TEST_SUITE_FAIL_COUNTER == 0 ? 0 : -1; \
+ }
+
+#define P_TEST_SUITE_RUN_CASE(a) \
+ printf ("Running test case: %s\n", #a); \
+ P_TEST_SUITE_FAIL_COUNTER += (p_test_case_##a)()
+
+#define P_TEST_CHECK(a) \
+ do { \
+ if (!(a)) { \
+ printf ("%s:%d: check failed\n", __FILE__, __LINE__); \
+ p_atomic_int_inc (&P_TEST_MODULE_FAIL_COUNTER); \
+ } \
+ } while (0)
+
+#define P_TEST_CHECK_CLOSE(a, b, eps) \
+ do { \
+ double p_test_eps_diff = (a) > (b) ? (a) - (b) : (b) - (a); \
+ double p_test_d1 = p_test_safe_division (p_test_eps_diff, \
+ ((a) < 0.0 ? (-(a)) : (a))); \
+ double p_test_d2 = p_test_safe_division (p_test_eps_diff, \
+ ((b) < 0.0 ? (-(b)) : (b))); \
+ double p_test_tol = (eps) * 0.01; \
+ \
+ if (!(p_test_d1 <= p_test_tol && p_test_d2 <= p_test_tol)) { \
+ printf ("%s:%d: check failed\n", __FILE__, __LINE__); \
+ p_atomic_int_inc (&P_TEST_MODULE_FAIL_COUNTER); \
+ } \
+ } while (0)
+
+#define P_TEST_REQUIRE(a) \
+ do { \
+ if (!(a)) { \
+ printf ("%s:%d: required check failed\n", __FILE__, __LINE__); \
+ exit (-1); \
+ } \
+ } while (0)
+
+#endif /* PLIBSYS_HEADER_PTESTMACROS_H */
diff --git a/3rdparty/plibsys/tests/ptimeprofiler_test.cpp b/3rdparty/plibsys/tests/ptimeprofiler_test.cpp
new file mode 100644
index 0000000..dd9e2b7
--- /dev/null
+++ b/3rdparty/plibsys/tests/ptimeprofiler_test.cpp
@@ -0,0 +1,126 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+P_TEST_CASE_BEGIN (ptimeprofiler_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_time_profiler_new () == NULL);
+
+ p_mem_restore_vtable ();
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptimeprofiler_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_time_profiler_elapsed_usecs (NULL) == 0);
+ p_time_profiler_reset (NULL);
+ p_time_profiler_free (NULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptimeprofiler_general_test)
+{
+ PTimeProfiler *profiler = NULL;
+ puint64 prev_val, val;
+
+ p_libsys_init ();
+
+ profiler = p_time_profiler_new ();
+ P_TEST_REQUIRE (profiler != NULL);
+
+ p_uthread_sleep (50);
+ prev_val = p_time_profiler_elapsed_usecs (profiler);
+ P_TEST_CHECK (prev_val > 0);
+
+ p_uthread_sleep (100);
+ val = p_time_profiler_elapsed_usecs (profiler);
+ P_TEST_CHECK (val > prev_val);
+ prev_val = val;
+
+ p_uthread_sleep (1000);
+ val = p_time_profiler_elapsed_usecs (profiler);
+ P_TEST_CHECK (val > prev_val);
+
+ p_time_profiler_reset (profiler);
+
+ p_uthread_sleep (15);
+ prev_val = p_time_profiler_elapsed_usecs (profiler);
+ P_TEST_CHECK (prev_val > 0);
+
+ p_uthread_sleep (178);
+ val = p_time_profiler_elapsed_usecs (profiler);
+ P_TEST_CHECK (val > prev_val);
+
+ p_time_profiler_free (profiler);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (ptimeprofiler_nomem_test);
+ P_TEST_SUITE_RUN_CASE (ptimeprofiler_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (ptimeprofiler_general_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/ptree_test.cpp b/3rdparty/plibsys/tests/ptree_test.cpp
new file mode 100644
index 0000000..e038ebb
--- /dev/null
+++ b/3rdparty/plibsys/tests/ptree_test.cpp
@@ -0,0 +1,633 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2015-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+
+P_TEST_MODULE_INIT ();
+
+#define PTREE_STRESS_ITERATIONS 20
+#define PTREE_STRESS_NODES 10000
+#define PTREE_STRESS_ROOT_MIN 10000
+#define PTREE_STRESS_TRAVS 30
+
+typedef struct _TreeData {
+ pint cmp_counter;
+ pint key_destroy_counter;
+ pint value_destroy_counter;
+ pint traverse_counter;
+ pint traverse_thres;
+ pint key_sum;
+ pint value_sum;
+ pint last_key;
+ pint key_order_errors;
+} TreeData;
+
+static TreeData tree_data = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+static pint
+tree_complexity (PTree *tree)
+{
+ if (tree == NULL || p_tree_get_nnodes (tree) == 0)
+ return 0;
+
+ switch (p_tree_get_type (tree)) {
+ case P_TREE_TYPE_BINARY:
+ return p_tree_get_nnodes (tree);
+ case P_TREE_TYPE_RB:
+ return 2 * ((pint) (log ((double) p_tree_get_nnodes (tree) + 1) / log (2.0)));
+ case P_TREE_TYPE_AVL:
+ {
+ double phi = (1 + sqrt (5.0)) / 2.0;
+ return (pint) (log (sqrt (5.0) * (p_tree_get_nnodes (tree) + 2)) / log (phi) - 2);
+ }
+ default:
+ return p_tree_get_nnodes (tree);
+ }
+}
+
+static pint
+compare_keys (pconstpointer a, pconstpointer b)
+{
+ int p1 = PPOINTER_TO_INT (a);
+ int p2 = PPOINTER_TO_INT (b);
+
+ if (p1 < p2)
+ return -1;
+ else if (p1 > p2)
+ return 1;
+ else
+ return 0;
+}
+
+static pint
+compare_keys_data (pconstpointer a, pconstpointer b, ppointer data)
+{
+ int p1 = PPOINTER_TO_INT (a);
+ int p2 = PPOINTER_TO_INT (b);
+
+ if (data != NULL)
+ ((TreeData *) data)->cmp_counter++;
+
+ if (p1 < p2)
+ return -1;
+ else if (p1 > p2)
+ return 1;
+ else
+ return 0;
+}
+
+static void
+key_destroy_notify (ppointer data)
+{
+ tree_data.key_destroy_counter++;
+ tree_data.key_sum += PPOINTER_TO_INT (data);
+}
+
+static void
+value_destroy_notify (ppointer data)
+{
+ tree_data.value_destroy_counter++;
+ tree_data.value_sum += PPOINTER_TO_INT (data);
+}
+
+static pboolean
+tree_traverse (ppointer key, ppointer value, ppointer data)
+{
+ TreeData* tdata = ((TreeData *) data);
+
+ tdata->key_sum += PPOINTER_TO_INT (key);
+ tdata->value_sum += PPOINTER_TO_INT (value);
+ tdata->traverse_counter++;
+
+ if (tdata->last_key >= PPOINTER_TO_INT (key))
+ tdata->key_order_errors++;
+
+ tdata->last_key = PPOINTER_TO_INT (key);
+
+ return FALSE;
+}
+
+static pboolean
+tree_traverse_thres (ppointer key, ppointer value, ppointer data)
+{
+ TreeData* tdata = ((TreeData *) data);
+
+ tree_traverse (key, value, data);
+
+ return tdata->traverse_counter >= tdata->traverse_thres ? TRUE : FALSE;
+}
+
+static bool
+check_tree_data_is_zero ()
+{
+ return tree_data.cmp_counter == 0 &&
+ tree_data.key_destroy_counter == 0 &&
+ tree_data.value_destroy_counter == 0 &&
+ tree_data.traverse_counter == 0 &&
+ tree_data.traverse_thres == 0 &&
+ tree_data.key_sum == 0 &&
+ tree_data.value_sum == 0 &&
+ tree_data.last_key == 0 &&
+ tree_data.key_order_errors == 0;
+}
+
+static bool
+general_tree_test (PTree *tree, PTreeType type, bool check_cmp, bool check_notify)
+{
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ P_TEST_REQUIRE (tree != NULL);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+ P_TEST_CHECK (p_tree_get_type (tree) == type);
+ P_TEST_CHECK (p_tree_lookup (tree, NULL) == NULL);
+ P_TEST_CHECK (p_tree_remove (tree, NULL) == FALSE);
+
+ p_tree_insert (tree, NULL, PINT_TO_POINTER (10));
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 1);
+ P_TEST_CHECK (p_tree_lookup (tree, NULL) == PINT_TO_POINTER (10));
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (2)) == NULL);
+ P_TEST_CHECK (p_tree_remove (tree, NULL) == TRUE);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ p_tree_foreach (tree, (PTraverseFunc) tree_traverse, &tree_data);
+ P_TEST_CHECK (tree_data.traverse_counter == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ /* Because we have NULL-key node */
+ P_TEST_CHECK (tree_data.key_sum == 0);
+
+ if (check_notify)
+ P_TEST_CHECK (tree_data.value_sum == 10);
+ else
+ P_TEST_CHECK (tree_data.value_sum == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ p_tree_insert (tree, PINT_TO_POINTER (4), PINT_TO_POINTER (40));
+ p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10));
+ p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (50));
+ p_tree_insert (tree, PINT_TO_POINTER (2), PINT_TO_POINTER (20));
+ p_tree_insert (tree, PINT_TO_POINTER (6), PINT_TO_POINTER (60));
+ p_tree_insert (tree, PINT_TO_POINTER (3), PINT_TO_POINTER (30));
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (100));
+ p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (500));
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10));
+ p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (50));
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0);
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ if (check_notify) {
+ P_TEST_CHECK (tree_data.key_sum == 12);
+ P_TEST_CHECK (tree_data.value_sum == 660);
+ } else {
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ }
+
+ P_TEST_CHECK (tree_data.traverse_counter == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ p_tree_foreach (tree, (PTraverseFunc) tree_traverse, &tree_data);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+ P_TEST_CHECK (tree_data.key_sum == 21);
+ P_TEST_CHECK (tree_data.value_sum == 210);
+ P_TEST_CHECK (tree_data.traverse_counter == 6);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ for (int i = 0; i < 7; ++i)
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10));
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0);
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ tree_data.cmp_counter = 0;
+
+ P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (7)) == FALSE);
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0 &&
+ tree_data.cmp_counter <= tree_complexity (tree));
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ if (check_notify) {
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ }
+
+ tree_data.cmp_counter = 0;
+
+ for (int i = 0; i < 7; ++i)
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10));
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0);
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ tree_data.traverse_thres = 5;
+
+ p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+ P_TEST_CHECK (tree_data.key_sum == 15);
+ P_TEST_CHECK (tree_data.value_sum == 150);
+ P_TEST_CHECK (tree_data.traverse_counter == 5);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ tree_data.traverse_thres = 3;
+
+ p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 6);
+
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+ P_TEST_CHECK (tree_data.key_sum == 6);
+ P_TEST_CHECK (tree_data.value_sum == 60);
+ P_TEST_CHECK (tree_data.traverse_counter == 3);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (1)) == TRUE);
+ P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (6)) == TRUE);
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (1)) == NULL);
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (6)) == NULL);
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0);
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ if (check_notify) {
+ P_TEST_CHECK (tree_data.key_sum == 7);
+ P_TEST_CHECK (tree_data.value_sum == 70);
+ } else {
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ }
+
+ tree_data.cmp_counter = 0;
+
+ for (int i = 2; i < 6; ++i)
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10));
+
+ if (check_cmp)
+ P_TEST_CHECK (tree_data.cmp_counter > 0);
+ else
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+
+ if (check_notify) {
+ P_TEST_CHECK (tree_data.key_sum == 7);
+ P_TEST_CHECK (tree_data.value_sum == 70);
+ } else {
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ }
+
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ tree_data.cmp_counter = 0;
+
+ p_tree_foreach (tree, NULL, NULL);
+
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ p_tree_clear (tree);
+
+ P_TEST_CHECK (tree_data.cmp_counter == 0);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+
+ if (check_notify) {
+ P_TEST_CHECK (tree_data.key_sum == 21);
+ P_TEST_CHECK (tree_data.value_sum == 210);
+ } else {
+ P_TEST_CHECK (tree_data.key_sum == 0);
+ P_TEST_CHECK (tree_data.value_sum == 0);
+ }
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ return true;
+}
+
+static bool
+stress_tree_test (PTree *tree, int node_count)
+{
+ P_TEST_REQUIRE (tree != NULL);
+ P_TEST_REQUIRE (node_count > 0);
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ srand ((unsigned int) time (NULL));
+
+ int counter = 0;
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ pint *keys = (pint *) p_malloc0 ((psize) node_count * sizeof (pint));
+ pint *values = (pint *) p_malloc0 ((psize) node_count * sizeof (pint));
+
+ P_TEST_REQUIRE (keys != NULL);
+ P_TEST_REQUIRE (values != NULL);
+
+ while (counter != node_count) {
+ pint rand_number = rand ();
+
+ if (counter == 0 && rand_number < PTREE_STRESS_ROOT_MIN)
+ continue;
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ if (p_tree_lookup (tree, PINT_TO_POINTER (rand_number)) != NULL)
+ continue;
+
+ if (counter > 0)
+ P_TEST_CHECK (tree_data.cmp_counter > 0 &&
+ tree_data.cmp_counter <= tree_complexity (tree));
+
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ keys[counter] = rand_number;
+ values[counter] = rand () + 1;
+
+ p_tree_insert (tree, PINT_TO_POINTER (keys[counter]), PINT_TO_POINTER (values[counter]));
+
+ if (counter > 0)
+ P_TEST_CHECK (tree_data.cmp_counter > 0 &&
+ tree_data.cmp_counter <= tree_complexity (tree));
+
+ ++counter;
+ }
+
+ for (int i = 0; i < PTREE_STRESS_TRAVS; ++i) {
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ tree_data.traverse_thres = i + 1;
+ tree_data.last_key = -1;
+
+ p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data);
+
+ P_TEST_CHECK (tree_data.traverse_counter == i + 1);
+ P_TEST_CHECK (tree_data.key_order_errors == 0);
+ }
+
+ for (int i = 0; i < node_count; ++i) {
+ memset (&tree_data, 0, sizeof (tree_data));
+
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (keys[i])) ==
+ PINT_TO_POINTER (values[i]));
+
+ P_TEST_CHECK (tree_data.cmp_counter > 0 &&
+ tree_data.cmp_counter <= tree_complexity (tree));
+
+ P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (keys[i])) == TRUE);
+ P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (keys[i])) == NULL);
+ }
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ for (int i = 0; i < node_count; ++i)
+ p_tree_insert (tree, PINT_TO_POINTER (keys[i]), PINT_TO_POINTER (values[i]));
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == node_count);
+
+ p_tree_clear (tree);
+
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ p_free (keys);
+ p_free (values);
+
+ return true;
+}
+
+P_TEST_CASE_BEGIN (ptree_nomem_test)
+{
+ p_libsys_init ();
+
+ PMemVTable vtable;
+
+ for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) {
+ PTree *tree = p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys);
+ P_TEST_CHECK (tree != NULL);
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ P_TEST_CHECK (p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys) == NULL);
+ p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10));
+ P_TEST_CHECK (p_tree_get_nnodes (tree) == 0);
+
+ p_mem_restore_vtable ();
+
+ p_tree_free (tree);
+ }
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptree_invalid_test)
+{
+ p_libsys_init ();
+
+ for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) {
+ /* Invalid usage */
+ P_TEST_CHECK (p_tree_new ((PTreeType) i, NULL) == NULL);
+ P_TEST_CHECK (p_tree_new ((PTreeType) -1, (PCompareFunc) compare_keys) == NULL);
+ P_TEST_CHECK (p_tree_new ((PTreeType) -1, NULL) == NULL);
+
+ P_TEST_CHECK (p_tree_new_with_data ((PTreeType) i, NULL, NULL) == NULL);
+ P_TEST_CHECK (p_tree_new_with_data ((PTreeType) -1, (PCompareDataFunc) compare_keys, NULL) == NULL);
+ P_TEST_CHECK (p_tree_new_with_data ((PTreeType) -1, NULL, NULL) == NULL);
+
+ P_TEST_CHECK (p_tree_new_full ((PTreeType) i,
+ NULL,
+ NULL,
+ NULL,
+ NULL) == NULL);
+ P_TEST_CHECK (p_tree_new_full ((PTreeType) -1,
+ (PCompareDataFunc) compare_keys,
+ NULL,
+ NULL,
+ NULL) == NULL);
+ P_TEST_CHECK (p_tree_new_full ((PTreeType) -1,
+ NULL,
+ NULL,
+ NULL,
+ NULL) == NULL);
+
+ P_TEST_CHECK (p_tree_remove (NULL, NULL) == FALSE);
+ P_TEST_CHECK (p_tree_lookup (NULL, NULL) == NULL);
+ P_TEST_CHECK (p_tree_get_type (NULL) == (PTreeType) -1);
+ P_TEST_CHECK (p_tree_get_nnodes (NULL) == 0);
+
+ p_tree_insert (NULL, NULL, NULL);
+ p_tree_foreach (NULL, NULL, NULL);
+ p_tree_clear (NULL);
+ p_tree_free (NULL);
+ }
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptree_general_test)
+{
+ PTree *tree;
+
+ p_libsys_init ();
+
+ for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) {
+ /* Test 1 */
+ tree = p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys);
+
+ P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, false, false) == true);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+ p_tree_free (tree);
+
+ P_TEST_CHECK (check_tree_data_is_zero () == true);
+
+ /* Test 2 */
+ tree = p_tree_new_with_data ((PTreeType) i,
+ (PCompareDataFunc) compare_keys_data,
+ &tree_data);
+
+ P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, true, false) == true);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+ p_tree_free (tree);
+
+ P_TEST_CHECK (check_tree_data_is_zero () == true);
+
+ /* Test 3 */
+ tree = p_tree_new_full ((PTreeType) i,
+ (PCompareDataFunc) compare_keys_data,
+ &tree_data,
+ (PDestroyFunc) key_destroy_notify,
+ (PDestroyFunc) value_destroy_notify);
+ P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, true, true) == true);
+
+ memset (&tree_data, 0, sizeof (tree_data));
+ p_tree_free (tree);
+
+ P_TEST_CHECK (check_tree_data_is_zero () == true);
+ }
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptree_stress_test)
+{
+ PTree *tree;
+
+ p_libsys_init ();
+
+ for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) {
+ tree = p_tree_new_full ((PTreeType) i,
+ (PCompareDataFunc) compare_keys_data,
+ &tree_data,
+ (PDestroyFunc) key_destroy_notify,
+ (PDestroyFunc) value_destroy_notify);
+
+ for (int j = 0; j < PTREE_STRESS_ITERATIONS; ++j)
+ P_TEST_CHECK (stress_tree_test (tree, PTREE_STRESS_NODES) == true);
+
+ p_tree_free (tree);
+ }
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (ptree_nomem_test);
+ P_TEST_SUITE_RUN_CASE (ptree_invalid_test);
+ P_TEST_SUITE_RUN_CASE (ptree_general_test);
+ P_TEST_SUITE_RUN_CASE (ptree_stress_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/ptypes_test.cpp b/3rdparty/plibsys/tests/ptypes_test.cpp
new file mode 100644
index 0000000..1e9c0e9
--- /dev/null
+++ b/3rdparty/plibsys/tests/ptypes_test.cpp
@@ -0,0 +1,456 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2014-2017 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+P_TEST_CASE_BEGIN (ptypes_general_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (P_BYTE_ORDER == P_LITTLE_ENDIAN ||
+ P_BYTE_ORDER == P_BIG_ENDIAN);
+
+ P_TEST_CHECK (sizeof (pint8) == 1);
+ P_TEST_CHECK (sizeof (puint8) == 1);
+ P_TEST_CHECK (sizeof (pint16) == 2);
+ P_TEST_CHECK (sizeof (puint16) == 2);
+ P_TEST_CHECK (sizeof (pint32) == 4);
+ P_TEST_CHECK (sizeof (puint32) == 4);
+ P_TEST_CHECK (sizeof (pint64) == 8);
+ P_TEST_CHECK (sizeof (puint64) == 8);
+ P_TEST_CHECK (sizeof (void *) == sizeof (ppointer));
+ P_TEST_CHECK (sizeof (const void *) == sizeof (pconstpointer));
+ P_TEST_CHECK (sizeof (int) == sizeof (pboolean));
+ P_TEST_CHECK (sizeof (char) == sizeof (pchar));
+ P_TEST_CHECK (sizeof (short) == sizeof (pshort));
+ P_TEST_CHECK (sizeof (int) == sizeof (pint));
+ P_TEST_CHECK (sizeof (long) == sizeof (plong));
+ P_TEST_CHECK (sizeof (unsigned char) == sizeof (puchar));
+ P_TEST_CHECK (sizeof (unsigned short) == sizeof (pushort));
+ P_TEST_CHECK (sizeof (unsigned int) == sizeof (puint));
+ P_TEST_CHECK (sizeof (unsigned long) == sizeof (pulong));
+ P_TEST_CHECK (sizeof (float) == sizeof (pfloat));
+ P_TEST_CHECK (sizeof (double) == sizeof (pdouble));
+ P_TEST_CHECK (sizeof (pintptr) == PLIBSYS_SIZEOF_VOID_P);
+ P_TEST_CHECK (sizeof (puintptr) == PLIBSYS_SIZEOF_VOID_P);
+ P_TEST_CHECK (sizeof (psize) == PLIBSYS_SIZEOF_SIZE_T);
+ P_TEST_CHECK (sizeof (pssize) == PLIBSYS_SIZEOF_SIZE_T);
+ P_TEST_CHECK (sizeof (plong) == PLIBSYS_SIZEOF_LONG);
+ P_TEST_CHECK (sizeof (pulong) == PLIBSYS_SIZEOF_LONG);
+ P_TEST_CHECK (sizeof (poffset) == 8);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptypes_pointers_convert_test)
+{
+ p_libsys_init ();
+
+ ppointer pointer = P_INT_TO_POINTER (128);
+ P_TEST_CHECK (P_POINTER_TO_INT (pointer) == 128);
+
+ pint pint_val = -64;
+ pointer = PINT_TO_POINTER (pint_val);
+ P_TEST_CHECK (PPOINTER_TO_INT (pointer) == -64);
+
+ puint puint_val = 64;
+ pointer = PUINT_TO_POINTER (puint_val);
+ P_TEST_CHECK (PPOINTER_TO_UINT (pointer) == 64);
+
+ psize psize_val = 1024;
+ pointer = PSIZE_TO_POINTER (psize_val);
+ P_TEST_CHECK (PPOINTER_TO_PSIZE (psize_val) == 1024);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptypes_min_max_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (P_MININT8 == (pint8) 0x80);
+ P_TEST_CHECK (P_MAXINT8 == (pint8) 0x7F);
+ P_TEST_CHECK (P_MAXUINT8 == (puint8) 0xFF);
+ P_TEST_CHECK (P_MININT16 == (pint16) 0x8000);
+ P_TEST_CHECK (P_MAXINT16 == (pint16) 0x7FFF);
+ P_TEST_CHECK (P_MAXUINT16 == (puint16) 0xFFFF);
+ P_TEST_CHECK (P_MININT32 == (pint32) 0x80000000);
+ P_TEST_CHECK (P_MAXINT32 == (pint32) 0x7FFFFFFF);
+ P_TEST_CHECK (P_MAXUINT32 == (puint32) 0xFFFFFFFF);
+ P_TEST_CHECK (P_MININT64 == (pint64) 0x8000000000000000LL);
+ P_TEST_CHECK (P_MAXINT64 == (pint64) 0x7FFFFFFFFFFFFFFFLL);
+ P_TEST_CHECK (P_MAXUINT64 == (puint64) 0xFFFFFFFFFFFFFFFFULL);
+
+ if (PLIBSYS_SIZEOF_SIZE_T == 8) {
+ P_TEST_CHECK (P_MINSSIZE == P_MININT64);
+ P_TEST_CHECK (P_MAXSSIZE == P_MAXINT64);
+ P_TEST_CHECK (P_MAXSIZE == P_MAXUINT64);
+
+ if (PLIBSYS_SIZEOF_LONG == 8) {
+ P_TEST_CHECK (P_MINSSIZE == P_MINLONG);
+ P_TEST_CHECK (P_MAXSSIZE == P_MAXLONG);
+ P_TEST_CHECK (P_MAXSIZE == P_MAXULONG);
+ }
+ } else {
+ P_TEST_CHECK (P_MINSSIZE == P_MININT32);
+ P_TEST_CHECK (P_MAXSSIZE == P_MAXINT32);
+ P_TEST_CHECK (P_MAXSIZE == P_MAXUINT32);
+
+ if (PLIBSYS_SIZEOF_LONG == 4) {
+ P_TEST_CHECK (P_MINSSIZE == P_MINLONG);
+ P_TEST_CHECK (P_MAXSSIZE == P_MAXLONG);
+ P_TEST_CHECK (P_MAXSIZE == P_MAXULONG);
+ }
+ }
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptypes_modifiers_test)
+{
+ p_libsys_init ();
+
+ psize size_val = 256;
+ printf ("%#" PSIZE_MODIFIER "x\n", size_val);
+ pssize ssize_val = -256;
+ printf ("%#" PSIZE_MODIFIER "x\n", ssize_val);
+
+ puintptr puintptr_val = 512;
+ printf ("%#" PINTPTR_MODIFIER "x\n", puintptr_val);
+ pintptr pintptr_val = -512;
+ printf ("%#" PINTPTR_MODIFIER "x\n", pintptr_val);
+
+ puint16 puint16_val = 1024;
+ printf ("%#" PINT16_MODIFIER "x\n", puint16_val);
+ pint16 pint16_val = -1024;
+ printf ("%#" PINT16_MODIFIER "x\n", pint16_val);
+
+ puint32 puint32_val = 2048;
+ printf ("%#" PINT32_MODIFIER "x\n", puint32_val);
+ pint32 pint32_val = -2048;
+ printf ("%#" PINT32_MODIFIER "x\n", pint32_val);
+
+ puint64 puint64_val = 4096;
+ printf ("%#" PINT64_MODIFIER "x\n", puint64_val);
+ pint64 pint64_val = -4096;
+ printf ("%#" PINT64_MODIFIER "x\n", pint64_val);
+
+ poffset poffset_val = 8192;
+ printf ("%#" POFFSET_MODIFIER "x\n", poffset_val);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptypes_formats_test)
+{
+ p_libsys_init ();
+
+ pssize ssize_val = -256;
+ printf ("%" PSSIZE_FORMAT "\n", ssize_val);
+ psize size_val = 256;
+ printf ("%" PSIZE_FORMAT "\n", size_val);
+
+ puintptr puintptr_val = 512;
+ printf ("%" PUINTPTR_FORMAT "\n", puintptr_val);
+ pintptr pintptr_val = -512;
+ printf ("%" PINTPTR_FORMAT "\n", pintptr_val);
+
+ puint16 puint16_val = 1024;
+ printf ("%" PUINT16_FORMAT "\n", puint16_val);
+ pint16 pint16_val = -1024;
+ printf ("%" PINT16_FORMAT "\n", pint16_val);
+
+ puint32 puint32_val = 2048;
+ printf ("%" PUINT32_FORMAT "\n", puint32_val);
+ pint32 pint32_val = -2048;
+ printf ("%" PINT32_FORMAT "\n", pint32_val);
+
+ puint64 puint64_val = 4096;
+ printf ("%" PUINT64_FORMAT "\n", puint64_val);
+ pint64 pint64_val = -4096;
+ printf ("%" PINT64_FORMAT "\n", pint64_val);
+
+ poffset poffset_val = 8192;
+ printf ("%" POFFSET_FORMAT "\n", poffset_val);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (ptypes_host_network_test)
+{
+ p_libsys_init ();
+
+ if (P_BYTE_ORDER == P_LITTLE_ENDIAN) {
+ pint16 pint16_val = PINT16_TO_BE (0xFFE0);
+ P_TEST_CHECK (pint16_val == (pint16) 0xE0FF);
+ P_TEST_CHECK (PINT16_FROM_BE (pint16_val) == (pint16) 0xFFE0);
+ P_TEST_CHECK (PINT16_TO_LE (pint16_val) == (pint16) 0xE0FF);
+ P_TEST_CHECK (PINT16_FROM_LE (pint16_val) == (pint16) 0xE0FF);
+
+ puint16 puint16_val = PUINT16_TO_BE (0x0020);
+ P_TEST_CHECK (puint16_val == (puint16) 0x2000);
+ P_TEST_CHECK (PUINT16_FROM_BE (puint16_val) == (puint16) 0x0020);
+ P_TEST_CHECK (PUINT16_TO_LE (puint16_val) == (puint16) 0x2000);
+ P_TEST_CHECK (PUINT16_FROM_LE (puint16_val) == (puint16) 0x2000);
+
+ pint32 pint32_val = PINT32_TO_BE (0xFFFFFFC0);
+ P_TEST_CHECK (pint32_val == (pint32) 0xC0FFFFFF);
+ P_TEST_CHECK (PINT32_FROM_BE (pint32_val) == (pint32) 0xFFFFFFC0);
+ P_TEST_CHECK (PINT32_TO_LE (pint32_val) == (pint32) 0xC0FFFFFF);
+ P_TEST_CHECK (PINT32_FROM_LE (pint32_val) == (pint32) 0xC0FFFFFF);
+
+ puint32 puint32_val = PUINT32_TO_BE (0x00000040);
+ P_TEST_CHECK (puint32_val == (puint32) 0x40000000);
+ P_TEST_CHECK (PUINT32_FROM_BE (puint32_val) == (puint32) 0x00000040);
+ P_TEST_CHECK (PUINT32_TO_LE (puint32_val) == (puint32) 0x40000000);
+ P_TEST_CHECK (PUINT32_FROM_LE (puint32_val) == (puint32) 0x40000000);
+
+ pint64 pint64_val = PINT64_TO_BE (0xFFFFFFFFFFFFFF80LL);
+ P_TEST_CHECK (pint64_val == (pint64) 0x80FFFFFFFFFFFFFFLL);
+ P_TEST_CHECK (PINT64_FROM_BE (pint64_val) == (pint64) 0xFFFFFFFFFFFFFF80LL);
+ P_TEST_CHECK (PINT64_TO_LE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL);
+ P_TEST_CHECK (PINT64_FROM_LE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL);
+
+ puint64 puint64_val = PUINT64_TO_BE (0x0000000000000080ULL);
+ P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL);
+ P_TEST_CHECK (PUINT64_FROM_BE (puint64_val) == (puint64) 0x0000000000000080ULL);
+ P_TEST_CHECK (PUINT64_TO_LE (puint64_val) == (puint64) 0x8000000000000000ULL);
+ P_TEST_CHECK (PUINT64_FROM_LE (puint64_val) == (puint64) 0x8000000000000000ULL);
+
+ pint pint_val = PINT_TO_BE (0xFFFFFC00);
+ P_TEST_CHECK (pint_val == (pint) 0x00FCFFFF);
+ P_TEST_CHECK (PINT_FROM_BE (pint_val) == (pint) 0xFFFFFC00);
+ P_TEST_CHECK (PINT_TO_LE (pint_val) == (pint) 0x00FCFFFF);
+ P_TEST_CHECK (PINT_FROM_LE (pint_val) == (pint) 0x00FCFFFF);
+
+ puint puint_val = PUINT_TO_BE (0x00000400);
+ P_TEST_CHECK (puint_val == (puint) 0x00040000);
+ P_TEST_CHECK (PUINT_FROM_BE (puint_val) == (puint) 0x00000400);
+ P_TEST_CHECK (PUINT_TO_LE (puint_val) == (puint) 0x00040000);
+ P_TEST_CHECK (PUINT_FROM_LE (puint_val) == (puint) 0x00040000);
+
+ if (PLIBSYS_SIZEOF_LONG == 8) {
+ plong plong_val = PLONG_TO_BE (0xFFFFFFFFFFFFF800LL);
+ P_TEST_CHECK (plong_val == (plong) 0x00F8FFFFFFFFFFFFLL);
+ P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0xFFFFFFFFFFFFF800LL);
+ P_TEST_CHECK (PLONG_TO_LE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL);
+ P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL);
+
+ pulong pulong_val = PULONG_TO_BE (0x0000000000000800ULL);
+ P_TEST_CHECK (pulong_val == (pulong) 0x0008000000000000ULL);
+ P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x0000000000000800ULL);
+ P_TEST_CHECK (PULONG_TO_LE (pulong_val) == (pulong) 0x0008000000000000ULL);
+ P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x0008000000000000ULL);
+ } else {
+ plong plong_val = PLONG_TO_BE (0xFFFFF800);
+ P_TEST_CHECK (plong_val == (plong) 0x00F8FFFF);
+ P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0xFFFFF800);
+ P_TEST_CHECK (PLONG_TO_LE (plong_val) == (plong) 0x00F8FFFF);
+ P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0x00F8FFFF);
+
+ pulong pulong_val = PULONG_TO_BE (0x00000800);
+ P_TEST_CHECK (pulong_val == (pulong) 0x00080000);
+ P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x00000800);
+ P_TEST_CHECK (PULONG_TO_LE (pulong_val) == (pulong) 0x00080000);
+ P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x00080000);
+ }
+
+ if (PLIBSYS_SIZEOF_SIZE_T == 8) {
+ psize psize_val = PSIZE_TO_BE (0x0000000000001000ULL);
+ P_TEST_CHECK (psize_val == (psize) 0x0010000000000000ULL);
+ P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x0000000000001000ULL);
+ P_TEST_CHECK (PSIZE_TO_LE (psize_val) == (psize) 0x0010000000000000ULL);
+ P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x0010000000000000ULL);
+
+ pssize pssize_val = PSSIZE_TO_BE (0x000000000000F000LL);
+ P_TEST_CHECK (pssize_val == (pssize) 0x00F0000000000000LL);
+ P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x000000000000F000LL);
+ P_TEST_CHECK (PSSIZE_TO_LE (pssize_val) == (pssize) 0x00F0000000000000LL);
+ P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x00F0000000000000LL);
+ } else {
+ psize psize_val = PSIZE_TO_BE (0x00001000);
+ P_TEST_CHECK (psize_val == (psize) 0x00100000);
+ P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x00001000);
+ P_TEST_CHECK (PSIZE_TO_LE (psize_val) == (psize) 0x00100000);
+ P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x00100000);
+
+ pssize pssize_val = PSSIZE_TO_BE (0x0000F000);
+ P_TEST_CHECK (pssize_val == (pssize) 0x00F00000);
+ P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x0000F000);
+ P_TEST_CHECK (PSSIZE_TO_LE (pssize_val) == (pssize) 0x00F00000);
+ P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x00F00000);
+ }
+
+ puint16_val = p_htons (0x0020);
+ P_TEST_CHECK (puint16_val == (puint16) 0x2000);
+ P_TEST_CHECK (p_ntohs (puint16_val) == (puint16) 0x0020);
+
+ puint32_val = p_htonl (0x00000040);
+ P_TEST_CHECK (puint32_val == (puint32) 0x40000000);
+ P_TEST_CHECK (p_ntohl (puint32_val) == (puint32) 0x00000040);
+ } else {
+ pint16 pint16_val = PINT16_TO_LE (0xFFE0);
+ P_TEST_CHECK (pint16_val == (pint16) 0xE0FF);
+ P_TEST_CHECK (PINT16_FROM_LE (pint16_val) == (pint16) 0xFFE0);
+ P_TEST_CHECK (PINT16_TO_BE (pint16_val) == (pint16) 0xE0FF);
+ P_TEST_CHECK (PINT16_FROM_BE (pint16_val) == (pint16) 0xE0FF);
+
+ puint16 puint16_val = PUINT16_TO_LE (0x0020);
+ P_TEST_CHECK (puint16_val == (puint16) 0x2000);
+ P_TEST_CHECK (PUINT16_FROM_LE (puint16_val) == (puint16) 0x0020);
+ P_TEST_CHECK (PUINT16_TO_BE (puint16_val) == (puint16) 0x2000);
+ P_TEST_CHECK (PUINT16_FROM_BE (puint16_val) == (puint16) 0x2000);
+
+ pint32 pint32_val = PINT32_TO_LE (0xFFFFFFC0);
+ P_TEST_CHECK (pint32_val == (pint32) 0xC0FFFFFF);
+ P_TEST_CHECK (PINT32_FROM_LE (pint32_val) == (pint32) 0xFFFFFFC0);
+ P_TEST_CHECK (PINT32_TO_BE (pint32_val) == (pint32) 0xC0FFFFFF);
+ P_TEST_CHECK (PINT32_FROM_BE (pint32_val) == (pint32) 0xC0FFFFFF);
+
+ puint32 puint32_val = PUINT32_TO_LE (0x00000040);
+ P_TEST_CHECK (puint32_val == (puint32) 0x40000000);
+ P_TEST_CHECK (PUINT32_FROM_LE (puint32_val) == (puint32) 0x00000040);
+ P_TEST_CHECK (PUINT32_TO_BE (puint32_val) == (puint32) 0x40000000);
+ P_TEST_CHECK (PUINT32_FROM_BE (puint32_val) == (puint32) 0x40000000);
+
+ pint64 pint64_val = PINT64_TO_LE (0xFFFFFFFFFFFFFF80LL);
+ P_TEST_CHECK (pint64_val == (pint64) 0x80FFFFFFFFFFFFFFLL);
+ P_TEST_CHECK (PINT64_FROM_LE (pint64_val) == (pint64) 0xFFFFFFFFFFFFFF80LL);
+ P_TEST_CHECK (PINT64_TO_BE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL);
+ P_TEST_CHECK (PINT64_FROM_BE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL);
+
+ puint64 puint64_val = PUINT64_TO_LE (0x0000000000000080ULL);
+ P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL);
+ P_TEST_CHECK (PUINT64_FROM_LE (puint64_val) == (puint64) 0x0000000000000080ULL);
+ P_TEST_CHECK (PUINT64_TO_BE (puint64_val) == (puint64) 0x8000000000000000ULL);
+ P_TEST_CHECK (PUINT64_FROM_BE (puint64_val) == (puint64) 0x8000000000000000ULL);
+
+ pint pint_val = PINT_TO_LE (0xFFFFFC00);
+ P_TEST_CHECK (pint_val == (pint) 0x00FCFFFF);
+ P_TEST_CHECK (PINT_FROM_LE (pint_val) == (pint) 0xFFFFFC00);
+ P_TEST_CHECK (PINT_TO_BE (pint_val) == (pint) 0x00FCFFFF);
+ P_TEST_CHECK (PINT_FROM_BE (pint_val) == (pint) 0x00FCFFFF);
+
+ puint puint_val = PUINT_TO_LE (0x00000400);
+ P_TEST_CHECK (puint_val == (puint) 0x00040000);
+ P_TEST_CHECK (PUINT_FROM_LE (puint_val) == (puint) 0x00000400);
+ P_TEST_CHECK (PUINT_TO_BE (puint_val) == (puint) 0x00040000);
+ P_TEST_CHECK (PUINT_FROM_BE (puint_val) == (puint) 0x00040000);
+
+ if (PLIBSYS_SIZEOF_LONG == 8) {
+ plong plong_val = PLONG_TO_LE (0xFFFFFFFFFFFFF800LL);
+ P_TEST_CHECK (plong_val == (plong) 0x00F8FFFFFFFFFFFFLL);
+ P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0xFFFFFFFFFFFFF800LL);
+ P_TEST_CHECK (PLONG_TO_BE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL);
+ P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL);
+
+ pulong pulong_val = PULONG_TO_LE (0x0000000000000800ULL);
+ P_TEST_CHECK (pulong_val == (pulong) 0x0008000000000000ULL);
+ P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x0000000000000800ULL);
+ P_TEST_CHECK (PULONG_TO_BE (pulong_val) == (pulong) 0x0008000000000000ULL);
+ P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x0008000000000000ULL);
+ } else {
+ plong plong_val = PLONG_TO_LE (0xFFFFF800);
+ P_TEST_CHECK (plong_val == (plong) 0x00F8FFFF);
+ P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0xFFFFF800);
+ P_TEST_CHECK (PLONG_TO_BE (plong_val) == (plong) 0x00F8FFFF);
+ P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0x00F8FFFF);
+
+ pulong pulong_val = PULONG_TO_LE (0x00000800);
+ P_TEST_CHECK (pulong_val == (pulong) 0x00080000);
+ P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x00000800);
+ P_TEST_CHECK (PULONG_TO_BE (pulong_val) == (pulong) 0x00080000);
+ P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x00080000);
+ }
+
+ if (PLIBSYS_SIZEOF_SIZE_T == 8) {
+ psize psize_val = PSIZE_TO_LE (0x0000000000001000ULL);
+ P_TEST_CHECK (psize_val == (psize) 0x0010000000000000ULL);
+ P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x0000000000001000ULL);
+ P_TEST_CHECK (PSIZE_TO_BE (psize_val) == (psize) 0x0010000000000000ULL);
+ P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x0010000000000000ULL);
+
+ pssize pssize_val = PSSIZE_TO_LE (0x000000000000F000LL);
+ P_TEST_CHECK (pssize_val == (pssize) 0x00F0000000000000LL);
+ P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x000000000000F000LL);
+ P_TEST_CHECK (PSSIZE_TO_BE (pssize_val) == (pssize) 0x00F0000000000000LL);
+ P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x00F0000000000000LL);
+ } else {
+ psize psize_val = PSIZE_TO_LE (0x00001000);
+ P_TEST_CHECK (psize_val == (psize) 0x00100000);
+ P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x00001000);
+ P_TEST_CHECK (PSIZE_TO_BE (psize_val) == (psize) 0x00100000);
+ P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x00100000);
+
+ pssize pssize_val = PSSIZE_TO_LE (0x0000F000);
+ P_TEST_CHECK (pssize_val == (pssize) 0x00F00000);
+ P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x0000F000);
+ P_TEST_CHECK (PSSIZE_TO_BE (pssize_val) == (pssize) 0x00F00000);
+ P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x00F00000);
+ }
+
+ puint16_val = p_htons (0x0020);
+ P_TEST_CHECK (puint16_val == (puint16) 0x0020);
+ P_TEST_CHECK (p_ntohs (puint16_val) == (puint16) 0x0020);
+
+ puint32_val = p_htonl (0x00000040);
+ P_TEST_CHECK (puint32_val == (puint32) 0x00000040);
+ P_TEST_CHECK (p_ntohl (puint32_val) == (puint32) 0x00000040);
+ }
+
+ puint16 puint16_val = PUINT16_SWAP_BYTES (0x0020);
+ P_TEST_CHECK (puint16_val == (puint16) 0x2000);
+ P_TEST_CHECK (PUINT16_SWAP_BYTES (puint16_val) == (puint16) 0x0020);
+
+ puint32 puint32_val = PUINT32_SWAP_BYTES (0x00000040);
+ P_TEST_CHECK (puint32_val == (puint32) 0x40000000);
+ P_TEST_CHECK (PUINT32_SWAP_BYTES (puint32_val) == (puint32) 0x00000040);
+
+ puint64 puint64_val = PUINT64_SWAP_BYTES (0x0000000000000080ULL);
+ P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL);
+ P_TEST_CHECK (PUINT64_SWAP_BYTES (puint64_val) == (puint64) 0x0000000000000080ULL);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (ptypes_general_test);
+ P_TEST_SUITE_RUN_CASE (ptypes_pointers_convert_test);
+ P_TEST_SUITE_RUN_CASE (ptypes_min_max_test);
+ P_TEST_SUITE_RUN_CASE (ptypes_modifiers_test);
+ P_TEST_SUITE_RUN_CASE (ptypes_formats_test);
+ P_TEST_SUITE_RUN_CASE (ptypes_host_network_test);
+}
+P_TEST_SUITE_END()
diff --git a/3rdparty/plibsys/tests/puthread_test.cpp b/3rdparty/plibsys/tests/puthread_test.cpp
new file mode 100644
index 0000000..5c31cd1
--- /dev/null
+++ b/3rdparty/plibsys/tests/puthread_test.cpp
@@ -0,0 +1,481 @@
+/*
+ * The MIT License
+ *
+ * Copyright (C) 2013-2019 Alexander Saprykin <saprykin.spb@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "plibsys.h"
+#include "ptestmacros.h"
+
+P_TEST_MODULE_INIT ();
+
+static pint thread_wakes_1 = 0;
+static pint thread_wakes_2 = 0;
+static pint thread_to_wakes = 0;
+static volatile pboolean is_threads_working = FALSE;
+
+static P_HANDLE thread1_id = (P_HANDLE) NULL;
+static P_HANDLE thread2_id = (P_HANDLE) NULL;
+static PUThread * thread1_obj = NULL;
+static PUThread * thread2_obj = NULL;
+
+static PUThreadKey * tls_key = NULL;
+static PUThreadKey * tls_key_2 = NULL;
+static volatile pint free_counter = 0;
+
+extern "C" ppointer pmem_alloc (psize nbytes)
+{
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
+{
+ P_UNUSED (block);
+ P_UNUSED (nbytes);
+ return (ppointer) NULL;
+}
+
+extern "C" void pmem_free (ppointer block)
+{
+ P_UNUSED (block);
+}
+
+extern "C" void free_with_check (ppointer mem)
+{
+ p_free (mem);
+ p_atomic_int_inc (&free_counter);
+}
+
+static void * test_thread_func (void *data)
+{
+ pint *counter = static_cast < pint * > (data);
+
+ if ((*counter) == 1) {
+ thread1_id = p_uthread_current_id ();
+ thread1_obj = p_uthread_current ();
+ } else {
+ thread2_id = p_uthread_current_id ();
+ thread2_obj = p_uthread_current ();
+ }
+
+ p_uthread_set_local (tls_key, (ppointer) p_uthread_current_id ());
+
+ *counter = 0;
+
+ while (is_threads_working == TRUE) {
+ p_uthread_sleep (10);
+ ++(*counter);
+ p_uthread_yield ();
+
+ if (p_uthread_get_local (tls_key) != (ppointer) p_uthread_current_id ())
+ p_uthread_exit (-1);
+ }
+
+ p_uthread_exit (*counter);
+
+ return NULL;
+}
+
+static void * test_thread_nonjoinable_func (void *data)
+{
+ pint *counter = static_cast < pint * > (data);
+
+ is_threads_working = TRUE;
+
+ for (int i = thread_to_wakes; i > 0; --i) {
+ p_uthread_sleep (10);
+ ++(*counter);
+ p_uthread_yield ();
+ }
+
+ is_threads_working = FALSE;
+
+ p_uthread_exit (0);
+
+ return NULL;
+}
+
+static void * test_thread_tls_func (void *data)
+{
+ pint self_thread_free = *((pint *) data);
+
+ pint *tls_value = (pint *) p_malloc0 (sizeof (pint));
+ *tls_value = 0;
+ p_uthread_set_local (tls_key, (ppointer) tls_value);
+
+ pint prev_tls = 0;
+ pint counter = 0;
+
+ while (is_threads_working == TRUE) {
+ p_uthread_sleep (10);
+
+ pint *last_tls = (pint *) p_uthread_get_local (tls_key);
+
+ if ((*last_tls) != prev_tls)
+ p_uthread_exit (-1);
+
+ pint *tls_new_value = (pint *) p_malloc0 (sizeof (pint));
+
+ *tls_new_value = (*last_tls) + 1;
+ prev_tls = (*last_tls) + 1;
+
+ p_uthread_replace_local (tls_key, (ppointer) tls_new_value);
+
+ if (self_thread_free)
+ p_free (last_tls);
+
+ ++counter;
+
+ p_uthread_yield ();
+ }
+
+ if (self_thread_free) {
+ pint *last_tls = (pint *) p_uthread_get_local (tls_key);
+
+ if ((*last_tls) != prev_tls)
+ p_uthread_exit (-1);
+
+ p_free (last_tls);
+
+ p_uthread_replace_local (tls_key, (ppointer) NULL);
+ }
+
+ p_uthread_exit (counter);
+
+ return NULL;
+}
+
+static void * test_thread_tls_create_func (void *data)
+{
+ P_UNUSED (data);
+
+ pint *tls_value = (pint *) p_malloc0 (sizeof (pint));
+ *tls_value = 0;
+ p_uthread_set_local (tls_key, (ppointer) tls_value);
+
+ pint *tls_value_2 = (pint *) p_malloc0 (sizeof (pint));
+ *tls_value_2 = 0;
+ p_uthread_set_local (tls_key_2, (ppointer) tls_value_2);
+
+ return NULL;
+}
+
+P_TEST_CASE_BEGIN (puthread_nomem_test)
+{
+ p_libsys_init ();
+
+ PUThreadKey *thread_key = p_uthread_local_new (p_free);
+ P_TEST_CHECK (thread_key != NULL);
+
+ PMemVTable vtable;
+
+ vtable.free = pmem_free;
+ vtable.malloc = pmem_alloc;
+ vtable.realloc = pmem_realloc;
+
+ P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE);
+
+ thread_wakes_1 = 0;
+ thread_wakes_2 = 0;
+
+ P_TEST_CHECK (p_uthread_create ((PUThreadFunc) test_thread_func,
+ (ppointer) &thread_wakes_1,
+ TRUE,
+ NULL) == NULL);
+
+ P_TEST_CHECK (p_uthread_create_full ((PUThreadFunc) test_thread_func,
+ (ppointer) &thread_wakes_2,
+ TRUE,
+ P_UTHREAD_PRIORITY_NORMAL,
+ 0,
+ NULL) == NULL);
+
+ P_TEST_CHECK (p_uthread_current () == NULL);
+ P_TEST_CHECK (p_uthread_local_new (NULL) == NULL);
+
+ p_uthread_exit (0);
+
+ p_uthread_set_local (thread_key, PINT_TO_POINTER (10));
+
+ ppointer tls_value = p_uthread_get_local (thread_key);
+
+ if (tls_value != NULL) {
+ P_TEST_CHECK (tls_value == PINT_TO_POINTER (10));
+ p_uthread_set_local (thread_key, NULL);
+ }
+
+ p_uthread_replace_local (thread_key, PINT_TO_POINTER (12));
+
+ tls_value = p_uthread_get_local (thread_key);
+
+ if (tls_value != NULL) {
+ P_TEST_CHECK (tls_value == PINT_TO_POINTER (12));
+ p_uthread_set_local (thread_key, NULL);
+ }
+
+ p_mem_restore_vtable ();
+
+ p_uthread_local_free (thread_key);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (puthread_bad_input_test)
+{
+ p_libsys_init ();
+
+ P_TEST_CHECK (p_uthread_create (NULL, NULL, FALSE, NULL) == NULL);
+ P_TEST_CHECK (p_uthread_create_full (NULL, NULL, FALSE, P_UTHREAD_PRIORITY_NORMAL, 0, NULL) == NULL);
+ P_TEST_CHECK (p_uthread_join (NULL) == -1);
+ P_TEST_CHECK (p_uthread_set_priority (NULL, P_UTHREAD_PRIORITY_NORMAL) == FALSE);
+ P_TEST_CHECK (p_uthread_get_local (NULL) == NULL);
+ p_uthread_set_local (NULL, NULL);
+ p_uthread_replace_local (NULL, NULL);
+ p_uthread_ref (NULL);
+ p_uthread_unref (NULL);
+ p_uthread_local_free (NULL);
+ p_uthread_exit (0);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (puthread_general_test)
+{
+ p_libsys_init ();
+
+ thread_wakes_1 = 1;
+ thread_wakes_2 = 2;
+ thread1_id = (P_HANDLE) NULL;
+ thread2_id = (P_HANDLE) NULL;
+ thread1_obj = NULL;
+ thread2_obj = NULL;
+
+ tls_key = p_uthread_local_new (NULL);
+ P_TEST_CHECK (tls_key != NULL);
+
+ /* Threre is no guarantee that we wouldn't get one of the IDs
+ * of the finished test threads */
+
+ P_HANDLE main_id = p_uthread_current_id ();
+
+ is_threads_working = TRUE;
+
+ PUThread *thr1 = p_uthread_create_full ((PUThreadFunc) test_thread_func,
+ (ppointer) &thread_wakes_1,
+ TRUE,
+ P_UTHREAD_PRIORITY_NORMAL,
+ 64 * 1024,
+ "thread_name");
+
+ PUThread *thr2 = p_uthread_create_full ((PUThreadFunc) test_thread_func,
+ (ppointer) &thread_wakes_2,
+ TRUE,
+ P_UTHREAD_PRIORITY_NORMAL,
+ 64 * 1024,
+ "very_long_name_for_thread_testing");
+
+ p_uthread_ref (thr1);
+
+ p_uthread_set_priority (thr1, P_UTHREAD_PRIORITY_NORMAL);
+
+ P_TEST_REQUIRE (thr1 != NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ p_uthread_sleep (5000);
+
+ is_threads_working = FALSE;
+
+ P_TEST_CHECK (p_uthread_join (thr1) == thread_wakes_1);
+ P_TEST_CHECK (p_uthread_join (thr2) == thread_wakes_2);
+
+ P_TEST_REQUIRE (thread1_id != thread2_id);
+ P_TEST_CHECK (thread1_id != main_id && thread2_id != main_id);
+
+ P_TEST_CHECK (thread1_obj == thr1);
+ P_TEST_CHECK (thread2_obj == thr2);
+
+ p_uthread_local_free (tls_key);
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ p_uthread_unref (thr1);
+
+ PUThread *cur_thr = p_uthread_current ();
+ P_TEST_CHECK (cur_thr != NULL);
+
+ P_TEST_CHECK (p_uthread_ideal_count () > 0);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (puthread_nonjoinable_test)
+{
+ p_libsys_init ();
+
+ thread_wakes_1 = 0;
+ thread_to_wakes = 100;
+ is_threads_working = TRUE;
+
+ PUThread *thr1 = p_uthread_create ((PUThreadFunc) test_thread_nonjoinable_func,
+ (ppointer) &thread_wakes_1,
+ FALSE,
+ NULL);
+
+ P_TEST_REQUIRE (thr1 != NULL);
+
+ p_uthread_sleep (3000);
+
+ P_TEST_CHECK (p_uthread_join (thr1) == -1);
+
+ while (is_threads_working == TRUE)
+ p_uthread_sleep (10);
+
+ P_TEST_CHECK (thread_wakes_1 == thread_to_wakes);
+
+ p_uthread_unref (thr1);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_CASE_BEGIN (puthread_tls_test)
+{
+ p_libsys_init ();
+
+ /* With destroy notification */
+ tls_key = p_uthread_local_new (free_with_check);
+
+ is_threads_working = TRUE;
+ free_counter = 0;
+
+ pint self_thread_free = 0;
+
+ PUThread *thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_func,
+ (ppointer) &self_thread_free,
+ TRUE,
+ NULL);
+
+ PUThread *thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_func,
+ (ppointer) &self_thread_free,
+ TRUE,
+ NULL);
+
+ P_TEST_REQUIRE (thr1 != NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ p_uthread_sleep (5000);
+
+ is_threads_working = FALSE;
+
+ pint total_counter = 0;
+
+ total_counter += (p_uthread_join (thr1) + 1);
+ total_counter += (p_uthread_join (thr2) + 1);
+
+ P_TEST_CHECK (total_counter == free_counter);
+
+ p_uthread_local_free (tls_key);
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ /* Without destroy notification */
+ tls_key = p_uthread_local_new (NULL);
+
+ free_counter = 0;
+ is_threads_working = TRUE;
+ self_thread_free = 1;
+
+ thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_func,
+ (ppointer) &self_thread_free,
+ TRUE,
+ NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_func,
+ (ppointer) &self_thread_free,
+ TRUE,
+ NULL);
+
+ P_TEST_REQUIRE (thr1 != NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ p_uthread_sleep (5000);
+
+ is_threads_working = FALSE;
+
+ total_counter = 0;
+
+ total_counter += (p_uthread_join (thr1) + 1);
+ total_counter += (p_uthread_join (thr2) + 1);
+
+ P_TEST_CHECK (total_counter > 0);
+ P_TEST_CHECK (free_counter == 0);
+
+ p_uthread_local_free (tls_key);
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ /* With implicit thread exit */
+ tls_key = p_uthread_local_new (free_with_check);
+ tls_key_2 = p_uthread_local_new (free_with_check);
+
+ free_counter = 0;
+
+ thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_create_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_create_func,
+ NULL,
+ TRUE,
+ NULL);
+
+ P_TEST_REQUIRE (thr1 != NULL);
+ P_TEST_REQUIRE (thr2 != NULL);
+
+ p_uthread_join (thr1);
+ p_uthread_join (thr2);
+
+ P_TEST_CHECK (free_counter == 4);
+
+ p_uthread_local_free (tls_key);
+ p_uthread_local_free (tls_key_2);
+ p_uthread_unref (thr1);
+ p_uthread_unref (thr2);
+
+ p_libsys_shutdown ();
+}
+P_TEST_CASE_END ()
+
+P_TEST_SUITE_BEGIN()
+{
+ P_TEST_SUITE_RUN_CASE (puthread_nomem_test);
+ P_TEST_SUITE_RUN_CASE (puthread_bad_input_test);
+ P_TEST_SUITE_RUN_CASE (puthread_general_test);
+ P_TEST_SUITE_RUN_CASE (puthread_nonjoinable_test);
+ P_TEST_SUITE_RUN_CASE (puthread_tls_test);
+}
+P_TEST_SUITE_END()
diff --git a/portaudio/.editorconfig b/3rdparty/portaudio/.editorconfig
index 88a2e5b..88a2e5b 100644
--- a/portaudio/.editorconfig
+++ b/3rdparty/portaudio/.editorconfig
diff --git a/portaudio/.gitattributes b/3rdparty/portaudio/.gitattributes
index 95d5134..95d5134 100644
--- a/portaudio/.gitattributes
+++ b/3rdparty/portaudio/.gitattributes
diff --git a/portaudio/.github/ISSUE_TEMPLATE/bug_report.md b/3rdparty/portaudio/.github/ISSUE_TEMPLATE/bug_report.md
index 794c5e9..794c5e9 100644
--- a/portaudio/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/3rdparty/portaudio/.github/ISSUE_TEMPLATE/bug_report.md
diff --git a/portaudio/.github/workflows/MSBuild.yml b/3rdparty/portaudio/.github/workflows/MSBuild.yml
index fa61d1a..fa61d1a 100644
--- a/portaudio/.github/workflows/MSBuild.yml
+++ b/3rdparty/portaudio/.github/workflows/MSBuild.yml
diff --git a/portaudio/.github/workflows/c-cpp.yml b/3rdparty/portaudio/.github/workflows/c-cpp.yml
index 180b46b..180b46b 100644
--- a/portaudio/.github/workflows/c-cpp.yml
+++ b/3rdparty/portaudio/.github/workflows/c-cpp.yml
diff --git a/portaudio/.gitignore b/3rdparty/portaudio/.gitignore
index ed72e3d..ed72e3d 100644
--- a/portaudio/.gitignore
+++ b/3rdparty/portaudio/.gitignore
diff --git a/portaudio/CMakeLists.txt b/3rdparty/portaudio/CMakeLists.txt
index 122fe93..122fe93 100644
--- a/portaudio/CMakeLists.txt
+++ b/3rdparty/portaudio/CMakeLists.txt
diff --git a/portaudio/Doxyfile b/3rdparty/portaudio/Doxyfile
index 1288182..1288182 100644
--- a/portaudio/Doxyfile
+++ b/3rdparty/portaudio/Doxyfile
diff --git a/portaudio/Doxyfile.developer b/3rdparty/portaudio/Doxyfile.developer
index c444652..c444652 100644
--- a/portaudio/Doxyfile.developer
+++ b/3rdparty/portaudio/Doxyfile.developer
diff --git a/portaudio/LICENSE.txt b/3rdparty/portaudio/LICENSE.txt
index e0ac4e8..e0ac4e8 100644
--- a/portaudio/LICENSE.txt
+++ b/3rdparty/portaudio/LICENSE.txt
diff --git a/portaudio/Makefile.in b/3rdparty/portaudio/Makefile.in
index 8eb7342..8eb7342 100644
--- a/portaudio/Makefile.in
+++ b/3rdparty/portaudio/Makefile.in
diff --git a/portaudio/README.configure.txt b/3rdparty/portaudio/README.configure.txt
index 6417d65..6417d65 100644
--- a/portaudio/README.configure.txt
+++ b/3rdparty/portaudio/README.configure.txt
diff --git a/portaudio/README.md b/3rdparty/portaudio/README.md
index bf48975..bf48975 100644
--- a/portaudio/README.md
+++ b/3rdparty/portaudio/README.md
diff --git a/portaudio/SConstruct b/3rdparty/portaudio/SConstruct
index 37e67ba..37e67ba 100644
--- a/portaudio/SConstruct
+++ b/3rdparty/portaudio/SConstruct
diff --git a/portaudio/aclocal.m4 b/3rdparty/portaudio/aclocal.m4
index f6850af..f6850af 100644
--- a/portaudio/aclocal.m4
+++ b/3rdparty/portaudio/aclocal.m4
diff --git a/portaudio/bindings/cpp/AUTHORS b/3rdparty/portaudio/bindings/cpp/AUTHORS
index e69de29..e69de29 100644
--- a/portaudio/bindings/cpp/AUTHORS
+++ b/3rdparty/portaudio/bindings/cpp/AUTHORS
diff --git a/portaudio/bindings/cpp/COPYING b/3rdparty/portaudio/bindings/cpp/COPYING
index c1c60a0..c1c60a0 100644
--- a/portaudio/bindings/cpp/COPYING
+++ b/3rdparty/portaudio/bindings/cpp/COPYING
diff --git a/portaudio/bindings/cpp/ChangeLog b/3rdparty/portaudio/bindings/cpp/ChangeLog
index 1e96618..1e96618 100644
--- a/portaudio/bindings/cpp/ChangeLog
+++ b/3rdparty/portaudio/bindings/cpp/ChangeLog
diff --git a/portaudio/bindings/cpp/INSTALL b/3rdparty/portaudio/bindings/cpp/INSTALL
index 2099840..2099840 100644
--- a/portaudio/bindings/cpp/INSTALL
+++ b/3rdparty/portaudio/bindings/cpp/INSTALL
diff --git a/portaudio/bindings/cpp/Makefile.am b/3rdparty/portaudio/bindings/cpp/Makefile.am
index b10449c..b10449c 100644
--- a/portaudio/bindings/cpp/Makefile.am
+++ b/3rdparty/portaudio/bindings/cpp/Makefile.am
diff --git a/portaudio/bindings/cpp/Makefile.in b/3rdparty/portaudio/bindings/cpp/Makefile.in
index a397933..a397933 100644
--- a/portaudio/bindings/cpp/Makefile.in
+++ b/3rdparty/portaudio/bindings/cpp/Makefile.in
diff --git a/portaudio/bindings/cpp/NEWS b/3rdparty/portaudio/bindings/cpp/NEWS
index e69de29..e69de29 100644
--- a/portaudio/bindings/cpp/NEWS
+++ b/3rdparty/portaudio/bindings/cpp/NEWS
diff --git a/portaudio/bindings/cpp/README b/3rdparty/portaudio/bindings/cpp/README
index e69de29..e69de29 100644
--- a/portaudio/bindings/cpp/README
+++ b/3rdparty/portaudio/bindings/cpp/README
diff --git a/portaudio/bindings/cpp/SConscript b/3rdparty/portaudio/bindings/cpp/SConscript
index e69b93a..e69b93a 100644
--- a/portaudio/bindings/cpp/SConscript
+++ b/3rdparty/portaudio/bindings/cpp/SConscript
diff --git a/portaudio/bindings/cpp/aclocal.m4 b/3rdparty/portaudio/bindings/cpp/aclocal.m4
index f5dec8f..f5dec8f 100644
--- a/portaudio/bindings/cpp/aclocal.m4
+++ b/3rdparty/portaudio/bindings/cpp/aclocal.m4
diff --git a/portaudio/bindings/cpp/bin/Makefile.am b/3rdparty/portaudio/bindings/cpp/bin/Makefile.am
index dcf3735..dcf3735 100644
--- a/portaudio/bindings/cpp/bin/Makefile.am
+++ b/3rdparty/portaudio/bindings/cpp/bin/Makefile.am
diff --git a/portaudio/bindings/cpp/bin/Makefile.in b/3rdparty/portaudio/bindings/cpp/bin/Makefile.in
index af20830..af20830 100644
--- a/portaudio/bindings/cpp/bin/Makefile.in
+++ b/3rdparty/portaudio/bindings/cpp/bin/Makefile.in
diff --git a/portaudio/bindings/cpp/configure b/3rdparty/portaudio/bindings/cpp/configure
index 0186597..0186597 100755
--- a/portaudio/bindings/cpp/configure
+++ b/3rdparty/portaudio/bindings/cpp/configure
diff --git a/portaudio/bindings/cpp/configure.ac b/3rdparty/portaudio/bindings/cpp/configure.ac
index 100656a..100656a 100644
--- a/portaudio/bindings/cpp/configure.ac
+++ b/3rdparty/portaudio/bindings/cpp/configure.ac
diff --git a/portaudio/bindings/cpp/doc/Makefile.am b/3rdparty/portaudio/bindings/cpp/doc/Makefile.am
index 7eb81ba..7eb81ba 100644
--- a/portaudio/bindings/cpp/doc/Makefile.am
+++ b/3rdparty/portaudio/bindings/cpp/doc/Makefile.am
diff --git a/portaudio/bindings/cpp/doc/Makefile.in b/3rdparty/portaudio/bindings/cpp/doc/Makefile.in
index f471ddc..f471ddc 100644
--- a/portaudio/bindings/cpp/doc/Makefile.in
+++ b/3rdparty/portaudio/bindings/cpp/doc/Makefile.in
diff --git a/portaudio/bindings/cpp/doc/README b/3rdparty/portaudio/bindings/cpp/doc/README
index efeaa72..efeaa72 100644
--- a/portaudio/bindings/cpp/doc/README
+++ b/3rdparty/portaudio/bindings/cpp/doc/README
diff --git a/portaudio/bindings/cpp/doc/config.doxy b/3rdparty/portaudio/bindings/cpp/doc/config.doxy
index 0bfe9d3..0bfe9d3 100644
--- a/portaudio/bindings/cpp/doc/config.doxy
+++ b/3rdparty/portaudio/bindings/cpp/doc/config.doxy
diff --git a/portaudio/bindings/cpp/doc/config.doxy.linux b/3rdparty/portaudio/bindings/cpp/doc/config.doxy.linux
index 95a38ef..95a38ef 100644
--- a/portaudio/bindings/cpp/doc/config.doxy.linux
+++ b/3rdparty/portaudio/bindings/cpp/doc/config.doxy.linux
diff --git a/portaudio/bindings/cpp/example/devs.cxx b/3rdparty/portaudio/bindings/cpp/example/devs.cxx
index 5ef4cab..5ef4cab 100644
--- a/portaudio/bindings/cpp/example/devs.cxx
+++ b/3rdparty/portaudio/bindings/cpp/example/devs.cxx
diff --git a/portaudio/bindings/cpp/example/sine.cxx b/3rdparty/portaudio/bindings/cpp/example/sine.cxx
index 0c772e6..0c772e6 100644
--- a/portaudio/bindings/cpp/example/sine.cxx
+++ b/3rdparty/portaudio/bindings/cpp/example/sine.cxx
diff --git a/portaudio/bindings/cpp/include/Makefile.am b/3rdparty/portaudio/bindings/cpp/include/Makefile.am
index f925657..f925657 100644
--- a/portaudio/bindings/cpp/include/Makefile.am
+++ b/3rdparty/portaudio/bindings/cpp/include/Makefile.am
diff --git a/portaudio/bindings/cpp/include/Makefile.in b/3rdparty/portaudio/bindings/cpp/include/Makefile.in
index 986651d..986651d 100644
--- a/portaudio/bindings/cpp/include/Makefile.in
+++ b/3rdparty/portaudio/bindings/cpp/include/Makefile.in
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx
index 59f6095..59f6095 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx
index 47e2ec1..47e2ec1 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx
index 158dfa0..158dfa0 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx
index 1c7faa8..1c7faa8 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx
index b306148..b306148 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx
index 7268b14..7268b14 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx
index 3f219ee..3f219ee 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx
index 0599582..0599582 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx
index bc24742..bc24742 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx
index 02d36b2..02d36b2 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx
index 113558c..113558c 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx
index 5aa49e7..5aa49e7 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx
index 01cf37b..01cf37b 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx
index 1165550..1165550 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx
index 1d3a1d9..1d3a1d9 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx
index a731930..a731930 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx
index c0ec9a9..c0ec9a9 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/System.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/System.hxx
index a159dc3..a159dc3 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/System.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/System.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx
index ffa195d..ffa195d 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx
diff --git a/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx
index 3e6a978..3e6a978 100644
--- a/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx
+++ b/3rdparty/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx
diff --git a/portaudio/bindings/cpp/lib/Makefile.am b/3rdparty/portaudio/bindings/cpp/lib/Makefile.am
index a27f7c5..a27f7c5 100644
--- a/portaudio/bindings/cpp/lib/Makefile.am
+++ b/3rdparty/portaudio/bindings/cpp/lib/Makefile.am
diff --git a/portaudio/bindings/cpp/lib/Makefile.in b/3rdparty/portaudio/bindings/cpp/lib/Makefile.in
index db0d614..db0d614 100644
--- a/portaudio/bindings/cpp/lib/Makefile.in
+++ b/3rdparty/portaudio/bindings/cpp/lib/Makefile.in
diff --git a/portaudio/bindings/cpp/portaudiocpp.pc.in b/3rdparty/portaudio/bindings/cpp/portaudiocpp.pc.in
index 8b126d1..8b126d1 100644
--- a/portaudio/bindings/cpp/portaudiocpp.pc.in
+++ b/3rdparty/portaudio/bindings/cpp/portaudiocpp.pc.in
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx
index 3efc100..3efc100 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx
index b26b9e8..b26b9e8 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx
index 9cceda9..9cceda9 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx
index 0137261..0137261 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx
index b6c8e1d..b6c8e1d 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx
index fe0b4ab..fe0b4ab 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx
index 7b21b03..7b21b03 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx
index 68453d0..68453d0 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx
index 98945c8..98945c8 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx
index 6a09670..6a09670 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx
index 5433fa3..5433fa3 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx
index 5141de2..5141de2 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx
index ba16e03..ba16e03 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx
index 5857710..5857710 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/System.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/System.cxx
index acb419d..acb419d 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/System.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/System.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx
index f94cf10..f94cf10 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx
diff --git a/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx
index 03f2d6e..03f2d6e 100644
--- a/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx
+++ b/3rdparty/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx
diff --git a/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c
index 64d8213..64d8213 100644
--- a/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c
+++ b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.c
diff --git a/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h
index e405fae..e405fae 100644
--- a/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h
+++ b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_BlockingStream.h
diff --git a/portaudio/bindings/java/c/src/com_portaudio_PortAudio.c b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.c
index 77c42eb..77c42eb 100644
--- a/portaudio/bindings/java/c/src/com_portaudio_PortAudio.c
+++ b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.c
diff --git a/portaudio/bindings/java/c/src/com_portaudio_PortAudio.h b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.h
index ed806ac..ed806ac 100644
--- a/portaudio/bindings/java/c/src/com_portaudio_PortAudio.h
+++ b/3rdparty/portaudio/bindings/java/c/src/com_portaudio_PortAudio.h
diff --git a/portaudio/bindings/java/c/src/jpa_tools.c b/3rdparty/portaudio/bindings/java/c/src/jpa_tools.c
index e3f903a..e3f903a 100644
--- a/portaudio/bindings/java/c/src/jpa_tools.c
+++ b/3rdparty/portaudio/bindings/java/c/src/jpa_tools.c
diff --git a/portaudio/bindings/java/c/src/jpa_tools.h b/3rdparty/portaudio/bindings/java/c/src/jpa_tools.h
index 11e724c..11e724c 100644
--- a/portaudio/bindings/java/c/src/jpa_tools.h
+++ b/3rdparty/portaudio/bindings/java/c/src/jpa_tools.h
diff --git a/portaudio/bindings/java/jportaudio.dox b/3rdparty/portaudio/bindings/java/jportaudio.dox
index f97b565..f97b565 100644
--- a/portaudio/bindings/java/jportaudio.dox
+++ b/3rdparty/portaudio/bindings/java/jportaudio.dox
diff --git a/portaudio/bindings/java/jportaudio/.classpath b/3rdparty/portaudio/bindings/java/jportaudio/.classpath
index 6bbd70c..6bbd70c 100644
--- a/portaudio/bindings/java/jportaudio/.classpath
+++ b/3rdparty/portaudio/bindings/java/jportaudio/.classpath
diff --git a/portaudio/bindings/java/jportaudio/.project b/3rdparty/portaudio/bindings/java/jportaudio/.project
index 8d2a750..8d2a750 100644
--- a/portaudio/bindings/java/jportaudio/.project
+++ b/3rdparty/portaudio/bindings/java/jportaudio/.project
diff --git a/portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java b/3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java
index ec2cb97..ec2cb97 100644
--- a/portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/PlaySine.java
diff --git a/portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java b/3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java
index 43b8fa7..43b8fa7 100644
--- a/portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/jtests/com/portaudio/TestBasic.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java
index 4c249ab..4c249ab 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/BlockingStream.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java
index 1c4682e..1c4682e 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/DeviceInfo.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java
index dc2cdce..dc2cdce 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/HostApiInfo.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java
index 41b3c67..41b3c67 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/PortAudio.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java
index 685f94d..685f94d 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamInfo.java
diff --git a/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java
index 707dab5..707dab5 100644
--- a/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java
+++ b/3rdparty/portaudio/bindings/java/jportaudio/src/com/portaudio/StreamParameters.java
diff --git a/portaudio/bindings/java/scripts/make_header.bat b/3rdparty/portaudio/bindings/java/scripts/make_header.bat
index 3c4f58a..3c4f58a 100644
--- a/portaudio/bindings/java/scripts/make_header.bat
+++ b/3rdparty/portaudio/bindings/java/scripts/make_header.bat
diff --git a/portaudio/clear_gitrevision.sh b/3rdparty/portaudio/clear_gitrevision.sh
index b1b087c..b1b087c 100755
--- a/portaudio/clear_gitrevision.sh
+++ b/3rdparty/portaudio/clear_gitrevision.sh
diff --git a/portaudio/cmake_support/FindASIOSDK.cmake b/3rdparty/portaudio/cmake_support/FindASIOSDK.cmake
index 55ad33d..55ad33d 100644
--- a/portaudio/cmake_support/FindASIOSDK.cmake
+++ b/3rdparty/portaudio/cmake_support/FindASIOSDK.cmake
diff --git a/portaudio/cmake_support/FindJack.cmake b/3rdparty/portaudio/cmake_support/FindJack.cmake
index 96e0b50..96e0b50 100644
--- a/portaudio/cmake_support/FindJack.cmake
+++ b/3rdparty/portaudio/cmake_support/FindJack.cmake
diff --git a/portaudio/cmake_support/cmake_uninstall.cmake.in b/3rdparty/portaudio/cmake_support/cmake_uninstall.cmake.in
index 2037e36..2037e36 100644
--- a/portaudio/cmake_support/cmake_uninstall.cmake.in
+++ b/3rdparty/portaudio/cmake_support/cmake_uninstall.cmake.in
diff --git a/portaudio/cmake_support/options_cmake.h.in b/3rdparty/portaudio/cmake_support/options_cmake.h.in
index cd07605..cd07605 100644
--- a/portaudio/cmake_support/options_cmake.h.in
+++ b/3rdparty/portaudio/cmake_support/options_cmake.h.in
diff --git a/portaudio/cmake_support/portaudio-2.0.pc.in b/3rdparty/portaudio/cmake_support/portaudio-2.0.pc.in
index 738803d..738803d 100644
--- a/portaudio/cmake_support/portaudio-2.0.pc.in
+++ b/3rdparty/portaudio/cmake_support/portaudio-2.0.pc.in
diff --git a/portaudio/cmake_support/portaudioConfig.cmake.in b/3rdparty/portaudio/cmake_support/portaudioConfig.cmake.in
index cacc476..cacc476 100644
--- a/portaudio/cmake_support/portaudioConfig.cmake.in
+++ b/3rdparty/portaudio/cmake_support/portaudioConfig.cmake.in
diff --git a/portaudio/cmake_support/template_portaudio.def b/3rdparty/portaudio/cmake_support/template_portaudio.def
index 9cf0dc3..9cf0dc3 100644
--- a/portaudio/cmake_support/template_portaudio.def
+++ b/3rdparty/portaudio/cmake_support/template_portaudio.def
diff --git a/portaudio/config.guess b/3rdparty/portaudio/config.guess
index b79252d..b79252d 100755
--- a/portaudio/config.guess
+++ b/3rdparty/portaudio/config.guess
diff --git a/portaudio/config.sub b/3rdparty/portaudio/config.sub
index 9633db7..9633db7 100755
--- a/portaudio/config.sub
+++ b/3rdparty/portaudio/config.sub
diff --git a/portaudio/configure b/3rdparty/portaudio/configure
index 2a59e10..2a59e10 100755
--- a/portaudio/configure
+++ b/3rdparty/portaudio/configure
diff --git a/portaudio/configure.in b/3rdparty/portaudio/configure.in
index bb4ae96..bb4ae96 100644
--- a/portaudio/configure.in
+++ b/3rdparty/portaudio/configure.in
diff --git a/portaudio/depcomp b/3rdparty/portaudio/depcomp
index 4ebd5b3..4ebd5b3 100755
--- a/portaudio/depcomp
+++ b/3rdparty/portaudio/depcomp
diff --git a/portaudio/doc/src/api_overview.dox b/3rdparty/portaudio/doc/src/api_overview.dox
index e5704ce..e5704ce 100644
--- a/portaudio/doc/src/api_overview.dox
+++ b/3rdparty/portaudio/doc/src/api_overview.dox
diff --git a/portaudio/doc/src/images/portaudio-external-architecture-diagram.png b/3rdparty/portaudio/doc/src/images/portaudio-external-architecture-diagram.png
index 64c0905..64c0905 100644
--- a/portaudio/doc/src/images/portaudio-external-architecture-diagram.png
+++ b/3rdparty/portaudio/doc/src/images/portaudio-external-architecture-diagram.png
Binary files differ
diff --git a/portaudio/doc/src/license.dox b/3rdparty/portaudio/doc/src/license.dox
index 8d0c51f..8d0c51f 100644
--- a/portaudio/doc/src/license.dox
+++ b/3rdparty/portaudio/doc/src/license.dox
diff --git a/portaudio/doc/src/mainpage.dox b/3rdparty/portaudio/doc/src/mainpage.dox
index 53e0060..53e0060 100644
--- a/portaudio/doc/src/mainpage.dox
+++ b/3rdparty/portaudio/doc/src/mainpage.dox
diff --git a/portaudio/doc/src/srcguide.dox b/3rdparty/portaudio/doc/src/srcguide.dox
index 26fd941..26fd941 100644
--- a/portaudio/doc/src/srcguide.dox
+++ b/3rdparty/portaudio/doc/src/srcguide.dox
diff --git a/portaudio/doc/src/tutorial/blocking_read_write.dox b/3rdparty/portaudio/doc/src/tutorial/blocking_read_write.dox
index 8905ee3..8905ee3 100644
--- a/portaudio/doc/src/tutorial/blocking_read_write.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/blocking_read_write.dox
diff --git a/portaudio/doc/src/tutorial/compile_cmake.dox b/3rdparty/portaudio/doc/src/tutorial/compile_cmake.dox
index 8db400e..8db400e 100644
--- a/portaudio/doc/src/tutorial/compile_cmake.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_cmake.dox
diff --git a/portaudio/doc/src/tutorial/compile_linux.dox b/3rdparty/portaudio/doc/src/tutorial/compile_linux.dox
index 2c993ca..2c993ca 100644
--- a/portaudio/doc/src/tutorial/compile_linux.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_linux.dox
diff --git a/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox b/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox
index 068391e..068391e 100644
--- a/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_mac_coreaudio.dox
diff --git a/portaudio/doc/src/tutorial/compile_windows.dox b/3rdparty/portaudio/doc/src/tutorial/compile_windows.dox
index 2258939..2258939 100644
--- a/portaudio/doc/src/tutorial/compile_windows.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_windows.dox
diff --git a/portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox b/3rdparty/portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox
index cf3a0e5..cf3a0e5 100644
--- a/portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_windows_asio_msvc.dox
diff --git a/portaudio/doc/src/tutorial/compile_windows_mingw.dox b/3rdparty/portaudio/doc/src/tutorial/compile_windows_mingw.dox
index 30143dc..30143dc 100644
--- a/portaudio/doc/src/tutorial/compile_windows_mingw.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/compile_windows_mingw.dox
diff --git a/portaudio/doc/src/tutorial/exploring.dox b/3rdparty/portaudio/doc/src/tutorial/exploring.dox
index 9dd0873..9dd0873 100644
--- a/portaudio/doc/src/tutorial/exploring.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/exploring.dox
diff --git a/portaudio/doc/src/tutorial/initializing_portaudio.dox b/3rdparty/portaudio/doc/src/tutorial/initializing_portaudio.dox
index 9439c35..9439c35 100644
--- a/portaudio/doc/src/tutorial/initializing_portaudio.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/initializing_portaudio.dox
diff --git a/portaudio/doc/src/tutorial/open_default_stream.dox b/3rdparty/portaudio/doc/src/tutorial/open_default_stream.dox
index 7512d1e..7512d1e 100644
--- a/portaudio/doc/src/tutorial/open_default_stream.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/open_default_stream.dox
diff --git a/portaudio/doc/src/tutorial/querying_devices.dox b/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox
index 1eac41a..1eac41a 100644
--- a/portaudio/doc/src/tutorial/querying_devices.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/querying_devices.dox
diff --git a/portaudio/doc/src/tutorial/start_stop_abort.dox b/3rdparty/portaudio/doc/src/tutorial/start_stop_abort.dox
index 0ddb460..0ddb460 100644
--- a/portaudio/doc/src/tutorial/start_stop_abort.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/start_stop_abort.dox
diff --git a/portaudio/doc/src/tutorial/terminating_portaudio.dox b/3rdparty/portaudio/doc/src/tutorial/terminating_portaudio.dox
index 67f74f6..67f74f6 100644
--- a/portaudio/doc/src/tutorial/terminating_portaudio.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/terminating_portaudio.dox
diff --git a/portaudio/doc/src/tutorial/tutorial_start.dox b/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox
index 42fa4bf..42fa4bf 100644
--- a/portaudio/doc/src/tutorial/tutorial_start.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/tutorial_start.dox
diff --git a/portaudio/doc/src/tutorial/utility_functions.dox b/3rdparty/portaudio/doc/src/tutorial/utility_functions.dox
index c06bf3b..c06bf3b 100644
--- a/portaudio/doc/src/tutorial/utility_functions.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/utility_functions.dox
diff --git a/portaudio/doc/src/tutorial/writing_a_callback.dox b/3rdparty/portaudio/doc/src/tutorial/writing_a_callback.dox
index f7d71b1..f7d71b1 100644
--- a/portaudio/doc/src/tutorial/writing_a_callback.dox
+++ b/3rdparty/portaudio/doc/src/tutorial/writing_a_callback.dox
diff --git a/portaudio/doc/utils/checkfiledocs.py b/3rdparty/portaudio/doc/utils/checkfiledocs.py
index 5d6b585..5d6b585 100644
--- a/portaudio/doc/utils/checkfiledocs.py
+++ b/3rdparty/portaudio/doc/utils/checkfiledocs.py
diff --git a/portaudio/examples/CMakeLists.txt b/3rdparty/portaudio/examples/CMakeLists.txt
index f96b6ec..f96b6ec 100644
--- a/portaudio/examples/CMakeLists.txt
+++ b/3rdparty/portaudio/examples/CMakeLists.txt
diff --git a/portaudio/examples/pa_devs.c b/3rdparty/portaudio/examples/pa_devs.c
index 27acfd5..27acfd5 100644
--- a/portaudio/examples/pa_devs.c
+++ b/3rdparty/portaudio/examples/pa_devs.c
diff --git a/portaudio/examples/pa_fuzz.c b/3rdparty/portaudio/examples/pa_fuzz.c
index 0c24d35..0c24d35 100644
--- a/portaudio/examples/pa_fuzz.c
+++ b/3rdparty/portaudio/examples/pa_fuzz.c
diff --git a/portaudio/examples/paex_mono_asio_channel_select.c b/3rdparty/portaudio/examples/paex_mono_asio_channel_select.c
index 4b55d31..4b55d31 100644
--- a/portaudio/examples/paex_mono_asio_channel_select.c
+++ b/3rdparty/portaudio/examples/paex_mono_asio_channel_select.c
diff --git a/portaudio/examples/paex_ocean_shore.c b/3rdparty/portaudio/examples/paex_ocean_shore.c
index 9424e8b..9424e8b 100644
--- a/portaudio/examples/paex_ocean_shore.c
+++ b/3rdparty/portaudio/examples/paex_ocean_shore.c
diff --git a/portaudio/examples/paex_pink.c b/3rdparty/portaudio/examples/paex_pink.c
index 519f979..519f979 100644
--- a/portaudio/examples/paex_pink.c
+++ b/3rdparty/portaudio/examples/paex_pink.c
diff --git a/portaudio/examples/paex_read_write_wire.c b/3rdparty/portaudio/examples/paex_read_write_wire.c
index b5046af..b5046af 100644
--- a/portaudio/examples/paex_read_write_wire.c
+++ b/3rdparty/portaudio/examples/paex_read_write_wire.c
diff --git a/portaudio/examples/paex_record.c b/3rdparty/portaudio/examples/paex_record.c
index 53bf571..53bf571 100644
--- a/portaudio/examples/paex_record.c
+++ b/3rdparty/portaudio/examples/paex_record.c
diff --git a/portaudio/examples/paex_record_file.c b/3rdparty/portaudio/examples/paex_record_file.c
index 562a8e9..562a8e9 100644
--- a/portaudio/examples/paex_record_file.c
+++ b/3rdparty/portaudio/examples/paex_record_file.c
diff --git a/portaudio/examples/paex_saw.c b/3rdparty/portaudio/examples/paex_saw.c
index caec0b0..caec0b0 100644
--- a/portaudio/examples/paex_saw.c
+++ b/3rdparty/portaudio/examples/paex_saw.c
diff --git a/portaudio/examples/paex_sine.c b/3rdparty/portaudio/examples/paex_sine.c
index 50ef205..50ef205 100644
--- a/portaudio/examples/paex_sine.c
+++ b/3rdparty/portaudio/examples/paex_sine.c
diff --git a/portaudio/examples/paex_sine_c++.cpp b/3rdparty/portaudio/examples/paex_sine_c++.cpp
index 5d96522..5d96522 100644
--- a/portaudio/examples/paex_sine_c++.cpp
+++ b/3rdparty/portaudio/examples/paex_sine_c++.cpp
diff --git a/portaudio/examples/paex_wmme_ac3.c b/3rdparty/portaudio/examples/paex_wmme_ac3.c
index 74daa96..74daa96 100644
--- a/portaudio/examples/paex_wmme_ac3.c
+++ b/3rdparty/portaudio/examples/paex_wmme_ac3.c
diff --git a/portaudio/examples/paex_wmme_surround.c b/3rdparty/portaudio/examples/paex_wmme_surround.c
index 55fc255..55fc255 100644
--- a/portaudio/examples/paex_wmme_surround.c
+++ b/3rdparty/portaudio/examples/paex_wmme_surround.c
diff --git a/portaudio/examples/paex_write_sine.c b/3rdparty/portaudio/examples/paex_write_sine.c
index 3035b42..3035b42 100644
--- a/portaudio/examples/paex_write_sine.c
+++ b/3rdparty/portaudio/examples/paex_write_sine.c
diff --git a/portaudio/examples/paex_write_sine_nonint.c b/3rdparty/portaudio/examples/paex_write_sine_nonint.c
index db78ed7..db78ed7 100644
--- a/portaudio/examples/paex_write_sine_nonint.c
+++ b/3rdparty/portaudio/examples/paex_write_sine_nonint.c
diff --git a/portaudio/i686-w64-mingw32.cmake b/3rdparty/portaudio/i686-w64-mingw32.cmake
index c3331b6..c3331b6 100644
--- a/portaudio/i686-w64-mingw32.cmake
+++ b/3rdparty/portaudio/i686-w64-mingw32.cmake
diff --git a/portaudio/include/pa_asio.h b/3rdparty/portaudio/include/pa_asio.h
index 27cbd3b..27cbd3b 100644
--- a/portaudio/include/pa_asio.h
+++ b/3rdparty/portaudio/include/pa_asio.h
diff --git a/portaudio/include/pa_jack.h b/3rdparty/portaudio/include/pa_jack.h
index 750d116..750d116 100644
--- a/portaudio/include/pa_jack.h
+++ b/3rdparty/portaudio/include/pa_jack.h
diff --git a/portaudio/include/pa_linux_alsa.h b/3rdparty/portaudio/include/pa_linux_alsa.h
index c940615..c940615 100644
--- a/portaudio/include/pa_linux_alsa.h
+++ b/3rdparty/portaudio/include/pa_linux_alsa.h
diff --git a/portaudio/include/pa_mac_core.h b/3rdparty/portaudio/include/pa_mac_core.h
index beb5396..beb5396 100644
--- a/portaudio/include/pa_mac_core.h
+++ b/3rdparty/portaudio/include/pa_mac_core.h
diff --git a/portaudio/include/pa_win_ds.h b/3rdparty/portaudio/include/pa_win_ds.h
index 8081abd..8081abd 100644
--- a/portaudio/include/pa_win_ds.h
+++ b/3rdparty/portaudio/include/pa_win_ds.h
diff --git a/portaudio/include/pa_win_wasapi.h b/3rdparty/portaudio/include/pa_win_wasapi.h
index c046afd..c046afd 100644
--- a/portaudio/include/pa_win_wasapi.h
+++ b/3rdparty/portaudio/include/pa_win_wasapi.h
diff --git a/portaudio/include/pa_win_waveformat.h b/3rdparty/portaudio/include/pa_win_waveformat.h
index 251562d..251562d 100644
--- a/portaudio/include/pa_win_waveformat.h
+++ b/3rdparty/portaudio/include/pa_win_waveformat.h
diff --git a/portaudio/include/pa_win_wdmks.h b/3rdparty/portaudio/include/pa_win_wdmks.h
index bc2f689..bc2f689 100644
--- a/portaudio/include/pa_win_wdmks.h
+++ b/3rdparty/portaudio/include/pa_win_wdmks.h
diff --git a/portaudio/include/pa_win_wmme.h b/3rdparty/portaudio/include/pa_win_wmme.h
index 814022b..814022b 100644
--- a/portaudio/include/pa_win_wmme.h
+++ b/3rdparty/portaudio/include/pa_win_wmme.h
diff --git a/portaudio/include/portaudio.h b/3rdparty/portaudio/include/portaudio.h
index 5d84731..5d84731 100644
--- a/portaudio/include/portaudio.h
+++ b/3rdparty/portaudio/include/portaudio.h
diff --git a/portaudio/install-sh b/3rdparty/portaudio/install-sh
index 377bb86..377bb86 100755
--- a/portaudio/install-sh
+++ b/3rdparty/portaudio/install-sh
diff --git a/portaudio/ltmain.sh b/3rdparty/portaudio/ltmain.sh
index 4a1ede7..4a1ede7 100644
--- a/portaudio/ltmain.sh
+++ b/3rdparty/portaudio/ltmain.sh
diff --git a/portaudio/missing b/3rdparty/portaudio/missing
index db98974..db98974 100755
--- a/portaudio/missing
+++ b/3rdparty/portaudio/missing
diff --git a/portaudio/pablio/README.txt b/3rdparty/portaudio/pablio/README.txt
index 84438bf..84438bf 100644
--- a/portaudio/pablio/README.txt
+++ b/3rdparty/portaudio/pablio/README.txt
diff --git a/portaudio/pablio/pablio.c b/3rdparty/portaudio/pablio/pablio.c
index 2275250..2275250 100644
--- a/portaudio/pablio/pablio.c
+++ b/3rdparty/portaudio/pablio/pablio.c
diff --git a/portaudio/pablio/pablio.def b/3rdparty/portaudio/pablio/pablio.def
index a10f952..a10f952 100644
--- a/portaudio/pablio/pablio.def
+++ b/3rdparty/portaudio/pablio/pablio.def
diff --git a/portaudio/pablio/pablio.h b/3rdparty/portaudio/pablio/pablio.h
index fbc3ef4..fbc3ef4 100644
--- a/portaudio/pablio/pablio.h
+++ b/3rdparty/portaudio/pablio/pablio.h
diff --git a/portaudio/pablio/test_rw.c b/3rdparty/portaudio/pablio/test_rw.c
index 029240d..029240d 100644
--- a/portaudio/pablio/test_rw.c
+++ b/3rdparty/portaudio/pablio/test_rw.c
diff --git a/portaudio/pablio/test_rw_echo.c b/3rdparty/portaudio/pablio/test_rw_echo.c
index 431587c..431587c 100644
--- a/portaudio/pablio/test_rw_echo.c
+++ b/3rdparty/portaudio/pablio/test_rw_echo.c
diff --git a/portaudio/pablio/test_w_saw.c b/3rdparty/portaudio/pablio/test_w_saw.c
index 2303d20..2303d20 100644
--- a/portaudio/pablio/test_w_saw.c
+++ b/3rdparty/portaudio/pablio/test_w_saw.c
diff --git a/portaudio/pablio/test_w_saw8.c b/3rdparty/portaudio/pablio/test_w_saw8.c
index 70686c1..70686c1 100644
--- a/portaudio/pablio/test_w_saw8.c
+++ b/3rdparty/portaudio/pablio/test_w_saw8.c
diff --git a/portaudio/portaudio-2.0.pc.in b/3rdparty/portaudio/portaudio-2.0.pc.in
index f5c1969..f5c1969 100644
--- a/portaudio/portaudio-2.0.pc.in
+++ b/3rdparty/portaudio/portaudio-2.0.pc.in
diff --git a/portaudio/qa/loopback/README.txt b/3rdparty/portaudio/qa/loopback/README.txt
index 5ad0280..5ad0280 100644
--- a/portaudio/qa/loopback/README.txt
+++ b/3rdparty/portaudio/qa/loopback/README.txt
diff --git a/portaudio/qa/loopback/src/audio_analyzer.c b/3rdparty/portaudio/qa/loopback/src/audio_analyzer.c
index fbdd631..fbdd631 100644
--- a/portaudio/qa/loopback/src/audio_analyzer.c
+++ b/3rdparty/portaudio/qa/loopback/src/audio_analyzer.c
diff --git a/portaudio/qa/loopback/src/audio_analyzer.h b/3rdparty/portaudio/qa/loopback/src/audio_analyzer.h
index 8d9f1ee..8d9f1ee 100644
--- a/portaudio/qa/loopback/src/audio_analyzer.h
+++ b/3rdparty/portaudio/qa/loopback/src/audio_analyzer.h
diff --git a/portaudio/qa/loopback/src/biquad_filter.c b/3rdparty/portaudio/qa/loopback/src/biquad_filter.c
index 1715fa3..1715fa3 100755
--- a/portaudio/qa/loopback/src/biquad_filter.c
+++ b/3rdparty/portaudio/qa/loopback/src/biquad_filter.c
diff --git a/portaudio/qa/loopback/src/biquad_filter.h b/3rdparty/portaudio/qa/loopback/src/biquad_filter.h
index 0895aba..0895aba 100755
--- a/portaudio/qa/loopback/src/biquad_filter.h
+++ b/3rdparty/portaudio/qa/loopback/src/biquad_filter.h
diff --git a/portaudio/qa/loopback/src/paqa.c b/3rdparty/portaudio/qa/loopback/src/paqa.c
index 5eb6283..5eb6283 100644
--- a/portaudio/qa/loopback/src/paqa.c
+++ b/3rdparty/portaudio/qa/loopback/src/paqa.c
diff --git a/portaudio/qa/loopback/src/paqa_tools.c b/3rdparty/portaudio/qa/loopback/src/paqa_tools.c
index 2e44c63..2e44c63 100644
--- a/portaudio/qa/loopback/src/paqa_tools.c
+++ b/3rdparty/portaudio/qa/loopback/src/paqa_tools.c
diff --git a/portaudio/qa/loopback/src/paqa_tools.h b/3rdparty/portaudio/qa/loopback/src/paqa_tools.h
index 77f6a25..77f6a25 100644
--- a/portaudio/qa/loopback/src/paqa_tools.h
+++ b/3rdparty/portaudio/qa/loopback/src/paqa_tools.h
diff --git a/portaudio/qa/loopback/src/qa_tools.h b/3rdparty/portaudio/qa/loopback/src/qa_tools.h
index 9b2debd..9b2debd 100755
--- a/portaudio/qa/loopback/src/qa_tools.h
+++ b/3rdparty/portaudio/qa/loopback/src/qa_tools.h
diff --git a/portaudio/qa/loopback/src/test_audio_analyzer.c b/3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.c
index 82fa859..82fa859 100644
--- a/portaudio/qa/loopback/src/test_audio_analyzer.c
+++ b/3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.c
diff --git a/portaudio/qa/loopback/src/test_audio_analyzer.h b/3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.h
index bfe073f..bfe073f 100644
--- a/portaudio/qa/loopback/src/test_audio_analyzer.h
+++ b/3rdparty/portaudio/qa/loopback/src/test_audio_analyzer.h
diff --git a/portaudio/qa/loopback/src/write_wav.c b/3rdparty/portaudio/qa/loopback/src/write_wav.c
index aa5ee21..aa5ee21 100755
--- a/portaudio/qa/loopback/src/write_wav.c
+++ b/3rdparty/portaudio/qa/loopback/src/write_wav.c
diff --git a/portaudio/qa/loopback/src/write_wav.h b/3rdparty/portaudio/qa/loopback/src/write_wav.h
index 3560055..3560055 100755
--- a/portaudio/qa/loopback/src/write_wav.h
+++ b/3rdparty/portaudio/qa/loopback/src/write_wav.h
diff --git a/portaudio/qa/paqa_devs.c b/3rdparty/portaudio/qa/paqa_devs.c
index 858ed78..858ed78 100644
--- a/portaudio/qa/paqa_devs.c
+++ b/3rdparty/portaudio/qa/paqa_devs.c
diff --git a/portaudio/qa/paqa_errs.c b/3rdparty/portaudio/qa/paqa_errs.c
index 8d4094f..8d4094f 100644
--- a/portaudio/qa/paqa_errs.c
+++ b/3rdparty/portaudio/qa/paqa_errs.c
diff --git a/portaudio/qa/paqa_latency.c b/3rdparty/portaudio/qa/paqa_latency.c
index a70807b..a70807b 100644
--- a/portaudio/qa/paqa_latency.c
+++ b/3rdparty/portaudio/qa/paqa_latency.c
diff --git a/portaudio/src/SConscript b/3rdparty/portaudio/src/SConscript
index 5cc9152..5cc9152 100644
--- a/portaudio/src/SConscript
+++ b/3rdparty/portaudio/src/SConscript
diff --git a/portaudio/src/common/pa_allocation.c b/3rdparty/portaudio/src/common/pa_allocation.c
index 7e3298a..7e3298a 100644
--- a/portaudio/src/common/pa_allocation.c
+++ b/3rdparty/portaudio/src/common/pa_allocation.c
diff --git a/portaudio/src/common/pa_allocation.h b/3rdparty/portaudio/src/common/pa_allocation.h
index 5c3cf53..5c3cf53 100644
--- a/portaudio/src/common/pa_allocation.h
+++ b/3rdparty/portaudio/src/common/pa_allocation.h
diff --git a/portaudio/src/common/pa_converters.c b/3rdparty/portaudio/src/common/pa_converters.c
index 93e44a3..93e44a3 100644
--- a/portaudio/src/common/pa_converters.c
+++ b/3rdparty/portaudio/src/common/pa_converters.c
diff --git a/portaudio/src/common/pa_converters.h b/3rdparty/portaudio/src/common/pa_converters.h
index 96edf1c..96edf1c 100644
--- a/portaudio/src/common/pa_converters.h
+++ b/3rdparty/portaudio/src/common/pa_converters.h
diff --git a/portaudio/src/common/pa_cpuload.c b/3rdparty/portaudio/src/common/pa_cpuload.c
index de57db2..de57db2 100644
--- a/portaudio/src/common/pa_cpuload.c
+++ b/3rdparty/portaudio/src/common/pa_cpuload.c
diff --git a/portaudio/src/common/pa_cpuload.h b/3rdparty/portaudio/src/common/pa_cpuload.h
index 8d3f618..8d3f618 100644
--- a/portaudio/src/common/pa_cpuload.h
+++ b/3rdparty/portaudio/src/common/pa_cpuload.h
diff --git a/portaudio/src/common/pa_debugprint.c b/3rdparty/portaudio/src/common/pa_debugprint.c
index 3e4024c..3e4024c 100644
--- a/portaudio/src/common/pa_debugprint.c
+++ b/3rdparty/portaudio/src/common/pa_debugprint.c
diff --git a/portaudio/src/common/pa_debugprint.h b/3rdparty/portaudio/src/common/pa_debugprint.h
index ca81724..ca81724 100644
--- a/portaudio/src/common/pa_debugprint.h
+++ b/3rdparty/portaudio/src/common/pa_debugprint.h
diff --git a/portaudio/src/common/pa_dither.c b/3rdparty/portaudio/src/common/pa_dither.c
index 0d1666a..0d1666a 100644
--- a/portaudio/src/common/pa_dither.c
+++ b/3rdparty/portaudio/src/common/pa_dither.c
diff --git a/portaudio/src/common/pa_dither.h b/3rdparty/portaudio/src/common/pa_dither.h
index 4f81123..4f81123 100644
--- a/portaudio/src/common/pa_dither.h
+++ b/3rdparty/portaudio/src/common/pa_dither.h
diff --git a/portaudio/src/common/pa_endianness.h b/3rdparty/portaudio/src/common/pa_endianness.h
index e074836..e074836 100644
--- a/portaudio/src/common/pa_endianness.h
+++ b/3rdparty/portaudio/src/common/pa_endianness.h
diff --git a/portaudio/src/common/pa_front.c b/3rdparty/portaudio/src/common/pa_front.c
index 65a656f..65a656f 100644
--- a/portaudio/src/common/pa_front.c
+++ b/3rdparty/portaudio/src/common/pa_front.c
diff --git a/portaudio/src/common/pa_gitrevision.h b/3rdparty/portaudio/src/common/pa_gitrevision.h
index b5a042c..b5a042c 100644
--- a/portaudio/src/common/pa_gitrevision.h
+++ b/3rdparty/portaudio/src/common/pa_gitrevision.h
diff --git a/portaudio/src/common/pa_hostapi.h b/3rdparty/portaudio/src/common/pa_hostapi.h
index 4ac3ab6..4ac3ab6 100644
--- a/portaudio/src/common/pa_hostapi.h
+++ b/3rdparty/portaudio/src/common/pa_hostapi.h
diff --git a/portaudio/src/common/pa_memorybarrier.h b/3rdparty/portaudio/src/common/pa_memorybarrier.h
index 0dca6aa..0dca6aa 100644
--- a/portaudio/src/common/pa_memorybarrier.h
+++ b/3rdparty/portaudio/src/common/pa_memorybarrier.h
diff --git a/portaudio/src/common/pa_process.c b/3rdparty/portaudio/src/common/pa_process.c
index 084cabb..084cabb 100644
--- a/portaudio/src/common/pa_process.c
+++ b/3rdparty/portaudio/src/common/pa_process.c
diff --git a/portaudio/src/common/pa_process.h b/3rdparty/portaudio/src/common/pa_process.h
index 444bdf5..444bdf5 100644
--- a/portaudio/src/common/pa_process.h
+++ b/3rdparty/portaudio/src/common/pa_process.h
diff --git a/portaudio/src/common/pa_ringbuffer.c b/3rdparty/portaudio/src/common/pa_ringbuffer.c
index b978d54..b978d54 100644
--- a/portaudio/src/common/pa_ringbuffer.c
+++ b/3rdparty/portaudio/src/common/pa_ringbuffer.c
diff --git a/portaudio/src/common/pa_ringbuffer.h b/3rdparty/portaudio/src/common/pa_ringbuffer.h
index 400aaac..400aaac 100644
--- a/portaudio/src/common/pa_ringbuffer.h
+++ b/3rdparty/portaudio/src/common/pa_ringbuffer.h
diff --git a/portaudio/src/common/pa_stream.c b/3rdparty/portaudio/src/common/pa_stream.c
index ffbf530..ffbf530 100644
--- a/portaudio/src/common/pa_stream.c
+++ b/3rdparty/portaudio/src/common/pa_stream.c
diff --git a/portaudio/src/common/pa_stream.h b/3rdparty/portaudio/src/common/pa_stream.h
index 4afda39..4afda39 100644
--- a/portaudio/src/common/pa_stream.h
+++ b/3rdparty/portaudio/src/common/pa_stream.h
diff --git a/portaudio/src/common/pa_trace.c b/3rdparty/portaudio/src/common/pa_trace.c
index 6763dfa..6763dfa 100644
--- a/portaudio/src/common/pa_trace.c
+++ b/3rdparty/portaudio/src/common/pa_trace.c
diff --git a/portaudio/src/common/pa_trace.h b/3rdparty/portaudio/src/common/pa_trace.h
index 7827766..7827766 100644
--- a/portaudio/src/common/pa_trace.h
+++ b/3rdparty/portaudio/src/common/pa_trace.h
diff --git a/portaudio/src/common/pa_types.h b/3rdparty/portaudio/src/common/pa_types.h
index f628783..f628783 100644
--- a/portaudio/src/common/pa_types.h
+++ b/3rdparty/portaudio/src/common/pa_types.h
diff --git a/portaudio/src/common/pa_util.h b/3rdparty/portaudio/src/common/pa_util.h
index 08dc0ec..08dc0ec 100644
--- a/portaudio/src/common/pa_util.h
+++ b/3rdparty/portaudio/src/common/pa_util.h
diff --git a/portaudio/src/hostapi/alsa/pa_linux_alsa.c b/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c
index a66f90d..a66f90d 100644
--- a/portaudio/src/hostapi/alsa/pa_linux_alsa.c
+++ b/3rdparty/portaudio/src/hostapi/alsa/pa_linux_alsa.c
diff --git a/portaudio/src/hostapi/asihpi/pa_linux_asihpi.c b/3rdparty/portaudio/src/hostapi/asihpi/pa_linux_asihpi.c
index 79eb1d7..79eb1d7 100644
--- a/portaudio/src/hostapi/asihpi/pa_linux_asihpi.c
+++ b/3rdparty/portaudio/src/hostapi/asihpi/pa_linux_asihpi.c
diff --git a/portaudio/src/hostapi/asio/ASIO-README.txt b/3rdparty/portaudio/src/hostapi/asio/ASIO-README.txt
index bc86caa..bc86caa 100644
--- a/portaudio/src/hostapi/asio/ASIO-README.txt
+++ b/3rdparty/portaudio/src/hostapi/asio/ASIO-README.txt
diff --git a/portaudio/src/hostapi/asio/Callback_adaptation_.pdf b/3rdparty/portaudio/src/hostapi/asio/Callback_adaptation_.pdf
index 76bf678..76bf678 100644
--- a/portaudio/src/hostapi/asio/Callback_adaptation_.pdf
+++ b/3rdparty/portaudio/src/hostapi/asio/Callback_adaptation_.pdf
Binary files differ
diff --git a/portaudio/src/hostapi/asio/Pa_ASIO.pdf b/3rdparty/portaudio/src/hostapi/asio/Pa_ASIO.pdf
index ac5ecad..ac5ecad 100644
--- a/portaudio/src/hostapi/asio/Pa_ASIO.pdf
+++ b/3rdparty/portaudio/src/hostapi/asio/Pa_ASIO.pdf
Binary files differ
diff --git a/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp b/3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp
index 08c55ea..08c55ea 100644
--- a/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp
+++ b/3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp
diff --git a/portaudio/src/hostapi/asio/iasiothiscallresolver.h b/3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.h
index 21d53b3..21d53b3 100644
--- a/portaudio/src/hostapi/asio/iasiothiscallresolver.h
+++ b/3rdparty/portaudio/src/hostapi/asio/iasiothiscallresolver.h
diff --git a/portaudio/src/hostapi/asio/pa_asio.cpp b/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp
index bc5f0e4..bc5f0e4 100644
--- a/portaudio/src/hostapi/asio/pa_asio.cpp
+++ b/3rdparty/portaudio/src/hostapi/asio/pa_asio.cpp
diff --git a/portaudio/src/hostapi/coreaudio/notes.txt b/3rdparty/portaudio/src/hostapi/coreaudio/notes.txt
index 281cf01..281cf01 100644
--- a/portaudio/src/hostapi/coreaudio/notes.txt
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/notes.txt
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core.c b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c
index 26b814c..26b814c 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core.c
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core.c
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c
index 70515f9..70515f9 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h
index c0e564a..c0e564a 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h
index d4a97e0..d4a97e0 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c
index 0d3b183..0d3b183 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c
diff --git a/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h
index c305f17..c305f17 100644
--- a/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h
+++ b/3rdparty/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h
diff --git a/portaudio/src/hostapi/dsound/pa_win_ds.c b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c
index 2ccb4f8..2ccb4f8 100644
--- a/portaudio/src/hostapi/dsound/pa_win_ds.c
+++ b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds.c
diff --git a/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c
index e54df99..e54df99 100644
--- a/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c
+++ b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c
diff --git a/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h
index 2cdf6f0..2cdf6f0 100644
--- a/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h
+++ b/3rdparty/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h
diff --git a/portaudio/src/hostapi/jack/pa_jack.c b/3rdparty/portaudio/src/hostapi/jack/pa_jack.c
index 124c0f8..124c0f8 100644
--- a/portaudio/src/hostapi/jack/pa_jack.c
+++ b/3rdparty/portaudio/src/hostapi/jack/pa_jack.c
diff --git a/portaudio/src/hostapi/oss/low_latency_tip.txt b/3rdparty/portaudio/src/hostapi/oss/low_latency_tip.txt
index 2d982b7..2d982b7 100644
--- a/portaudio/src/hostapi/oss/low_latency_tip.txt
+++ b/3rdparty/portaudio/src/hostapi/oss/low_latency_tip.txt
Binary files differ
diff --git a/portaudio/src/hostapi/oss/pa_unix_oss.c b/3rdparty/portaudio/src/hostapi/oss/pa_unix_oss.c
index 20113e2..20113e2 100644
--- a/portaudio/src/hostapi/oss/pa_unix_oss.c
+++ b/3rdparty/portaudio/src/hostapi/oss/pa_unix_oss.c
diff --git a/portaudio/src/hostapi/oss/recplay.c b/3rdparty/portaudio/src/hostapi/oss/recplay.c
index fe6dfdb..fe6dfdb 100644
--- a/portaudio/src/hostapi/oss/recplay.c
+++ b/3rdparty/portaudio/src/hostapi/oss/recplay.c
diff --git a/portaudio/src/hostapi/skeleton/README.txt b/3rdparty/portaudio/src/hostapi/skeleton/README.txt
index 39d4c8d..39d4c8d 100644
--- a/portaudio/src/hostapi/skeleton/README.txt
+++ b/3rdparty/portaudio/src/hostapi/skeleton/README.txt
diff --git a/portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c b/3rdparty/portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c
index 46808d2..46808d2 100644
--- a/portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c
+++ b/3rdparty/portaudio/src/hostapi/skeleton/pa_hostapi_skeleton.c
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h
index 91e7213..91e7213 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/AudioSessionTypes.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h
index 84832d9..84832d9 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/PropIdl.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h
index cd11186..cd11186 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ShTypes.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/audioclient.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/audioclient.h
index 60db0cd..60db0cd 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/audioclient.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/audioclient.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h
index 7a1f75c..7a1f75c 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/devicetopology.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h
index 81155d7..81155d7 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/endpointvolume.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h
index 7e07292..7e07292 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h
index d66cb97..d66cb97 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/functiondiscoverykeys_devpkey.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ks.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ks.h
index 2261e6c..2261e6c 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ks.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ks.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ksguid.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksguid.h
index f0774d0..f0774d0 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ksguid.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksguid.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h
index f029b01..f029b01 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksmedia.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h
index fcbc6b3..fcbc6b3 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksproxy.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h
index 7d0efff..7d0efff 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/ksuuids.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h
index a75e475..a75e475 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/mmdeviceapi.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/propkey.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkey.h
index 5b68236..5b68236 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/propkey.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkey.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h
index a361044..a361044 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propkeydef.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/propsys.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propsys.h
index 5ed5608..5ed5608 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/propsys.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/propsys.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h
index ba9836a..ba9836a 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/rpcsal.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/sal.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sal.h
index 3f99ab9..3f99ab9 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/sal.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sal.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h
index 44b5fb2..44b5fb2 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/sdkddkver.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h
index bca20a9..bca20a9 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/structuredquery.h
diff --git a/portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h
index 388d5f0..388d5f0 100644
--- a/portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h
+++ b/3rdparty/portaudio/src/hostapi/wasapi/mingw-include/winapifamily.h
diff --git a/portaudio/src/hostapi/wasapi/pa_win_wasapi.c b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c
index c76f302..c76f302 100644
--- a/portaudio/src/hostapi/wasapi/pa_win_wasapi.c
+++ b/3rdparty/portaudio/src/hostapi/wasapi/pa_win_wasapi.c
diff --git a/portaudio/src/hostapi/wasapi/readme.txt b/3rdparty/portaudio/src/hostapi/wasapi/readme.txt
index 0cfa0fa..0cfa0fa 100644
--- a/portaudio/src/hostapi/wasapi/readme.txt
+++ b/3rdparty/portaudio/src/hostapi/wasapi/readme.txt
diff --git a/portaudio/src/hostapi/wdmks/pa_win_wdmks.c b/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c
index 161c264..161c264 100644
--- a/portaudio/src/hostapi/wdmks/pa_win_wdmks.c
+++ b/3rdparty/portaudio/src/hostapi/wdmks/pa_win_wdmks.c
diff --git a/portaudio/src/hostapi/wdmks/readme.txt b/3rdparty/portaudio/src/hostapi/wdmks/readme.txt
index 611acc7..611acc7 100644
--- a/portaudio/src/hostapi/wdmks/readme.txt
+++ b/3rdparty/portaudio/src/hostapi/wdmks/readme.txt
diff --git a/portaudio/src/hostapi/wmme/pa_win_wmme.c b/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c
index f8b1d7e..f8b1d7e 100644
--- a/portaudio/src/hostapi/wmme/pa_win_wmme.c
+++ b/3rdparty/portaudio/src/hostapi/wmme/pa_win_wmme.c
diff --git a/portaudio/src/os/unix/pa_unix_hostapis.c b/3rdparty/portaudio/src/os/unix/pa_unix_hostapis.c
index 7f1a51f..7f1a51f 100644
--- a/portaudio/src/os/unix/pa_unix_hostapis.c
+++ b/3rdparty/portaudio/src/os/unix/pa_unix_hostapis.c
diff --git a/portaudio/src/os/unix/pa_unix_util.c b/3rdparty/portaudio/src/os/unix/pa_unix_util.c
index 459b2be..459b2be 100644
--- a/portaudio/src/os/unix/pa_unix_util.c
+++ b/3rdparty/portaudio/src/os/unix/pa_unix_util.c
diff --git a/portaudio/src/os/unix/pa_unix_util.h b/3rdparty/portaudio/src/os/unix/pa_unix_util.h
index 2228cb3..2228cb3 100644
--- a/portaudio/src/os/unix/pa_unix_util.h
+++ b/3rdparty/portaudio/src/os/unix/pa_unix_util.h
diff --git a/portaudio/src/os/win/pa_win_coinitialize.c b/3rdparty/portaudio/src/os/win/pa_win_coinitialize.c
index cdb1fb9..cdb1fb9 100644
--- a/portaudio/src/os/win/pa_win_coinitialize.c
+++ b/3rdparty/portaudio/src/os/win/pa_win_coinitialize.c
diff --git a/portaudio/src/os/win/pa_win_coinitialize.h b/3rdparty/portaudio/src/os/win/pa_win_coinitialize.h
index deb60c3..deb60c3 100644
--- a/portaudio/src/os/win/pa_win_coinitialize.h
+++ b/3rdparty/portaudio/src/os/win/pa_win_coinitialize.h
diff --git a/portaudio/src/os/win/pa_win_hostapis.c b/3rdparty/portaudio/src/os/win/pa_win_hostapis.c
index f8a4651..f8a4651 100644
--- a/portaudio/src/os/win/pa_win_hostapis.c
+++ b/3rdparty/portaudio/src/os/win/pa_win_hostapis.c
diff --git a/portaudio/src/os/win/pa_win_util.c b/3rdparty/portaudio/src/os/win/pa_win_util.c
index b86f7af..b86f7af 100644
--- a/portaudio/src/os/win/pa_win_util.c
+++ b/3rdparty/portaudio/src/os/win/pa_win_util.c
diff --git a/portaudio/src/os/win/pa_win_waveformat.c b/3rdparty/portaudio/src/os/win/pa_win_waveformat.c
index 0436a39..0436a39 100644
--- a/portaudio/src/os/win/pa_win_waveformat.c
+++ b/3rdparty/portaudio/src/os/win/pa_win_waveformat.c
diff --git a/portaudio/src/os/win/pa_win_wdmks_utils.c b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c
index 3373146..3373146 100644
--- a/portaudio/src/os/win/pa_win_wdmks_utils.c
+++ b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c
diff --git a/portaudio/src/os/win/pa_win_wdmks_utils.h b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.h
index f524cf7..f524cf7 100644
--- a/portaudio/src/os/win/pa_win_wdmks_utils.h
+++ b/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.h
diff --git a/portaudio/src/os/win/pa_x86_plain_converters.c b/3rdparty/portaudio/src/os/win/pa_x86_plain_converters.c
index 1096994..1096994 100644
--- a/portaudio/src/os/win/pa_x86_plain_converters.c
+++ b/3rdparty/portaudio/src/os/win/pa_x86_plain_converters.c
diff --git a/portaudio/src/os/win/pa_x86_plain_converters.h b/3rdparty/portaudio/src/os/win/pa_x86_plain_converters.h
index 8914ed1..8914ed1 100644
--- a/portaudio/src/os/win/pa_x86_plain_converters.h
+++ b/3rdparty/portaudio/src/os/win/pa_x86_plain_converters.h
diff --git a/portaudio/test/CMakeLists.txt b/3rdparty/portaudio/test/CMakeLists.txt
index 973568f..973568f 100644
--- a/portaudio/test/CMakeLists.txt
+++ b/3rdparty/portaudio/test/CMakeLists.txt
diff --git a/portaudio/test/README.txt b/3rdparty/portaudio/test/README.txt
index 7cce15e..7cce15e 100644
--- a/portaudio/test/README.txt
+++ b/3rdparty/portaudio/test/README.txt
diff --git a/portaudio/test/pa_minlat.c b/3rdparty/portaudio/test/pa_minlat.c
index 683b2bb..683b2bb 100644
--- a/portaudio/test/pa_minlat.c
+++ b/3rdparty/portaudio/test/pa_minlat.c
diff --git a/portaudio/test/patest1.c b/3rdparty/portaudio/test/patest1.c
index 25d6e3f..25d6e3f 100644
--- a/portaudio/test/patest1.c
+++ b/3rdparty/portaudio/test/patest1.c
diff --git a/portaudio/test/patest_buffer.c b/3rdparty/portaudio/test/patest_buffer.c
index d19e121..d19e121 100644
--- a/portaudio/test/patest_buffer.c
+++ b/3rdparty/portaudio/test/patest_buffer.c
diff --git a/portaudio/test/patest_callbackstop.c b/3rdparty/portaudio/test/patest_callbackstop.c
index fba9dca..fba9dca 100644
--- a/portaudio/test/patest_callbackstop.c
+++ b/3rdparty/portaudio/test/patest_callbackstop.c
diff --git a/portaudio/test/patest_clip.c b/3rdparty/portaudio/test/patest_clip.c
index 77989f4..77989f4 100644
--- a/portaudio/test/patest_clip.c
+++ b/3rdparty/portaudio/test/patest_clip.c
diff --git a/portaudio/test/patest_converters.c b/3rdparty/portaudio/test/patest_converters.c
index f76738c..f76738c 100644
--- a/portaudio/test/patest_converters.c
+++ b/3rdparty/portaudio/test/patest_converters.c
diff --git a/portaudio/test/patest_dither.c b/3rdparty/portaudio/test/patest_dither.c
index fc402dc..fc402dc 100644
--- a/portaudio/test/patest_dither.c
+++ b/3rdparty/portaudio/test/patest_dither.c
diff --git a/portaudio/test/patest_dsound_find_best_latency_params.c b/3rdparty/portaudio/test/patest_dsound_find_best_latency_params.c
index 1c074ab..1c074ab 100644
--- a/portaudio/test/patest_dsound_find_best_latency_params.c
+++ b/3rdparty/portaudio/test/patest_dsound_find_best_latency_params.c
diff --git a/portaudio/test/patest_dsound_low_level_latency_params.c b/3rdparty/portaudio/test/patest_dsound_low_level_latency_params.c
index d583e69..d583e69 100644
--- a/portaudio/test/patest_dsound_low_level_latency_params.c
+++ b/3rdparty/portaudio/test/patest_dsound_low_level_latency_params.c
diff --git a/portaudio/test/patest_dsound_surround.c b/3rdparty/portaudio/test/patest_dsound_surround.c
index b7c887d..b7c887d 100644
--- a/portaudio/test/patest_dsound_surround.c
+++ b/3rdparty/portaudio/test/patest_dsound_surround.c
diff --git a/portaudio/test/patest_hang.c b/3rdparty/portaudio/test/patest_hang.c
index 501b47d..501b47d 100644
--- a/portaudio/test/patest_hang.c
+++ b/3rdparty/portaudio/test/patest_hang.c
diff --git a/portaudio/test/patest_in_overflow.c b/3rdparty/portaudio/test/patest_in_overflow.c
index 31868bd..31868bd 100644
--- a/portaudio/test/patest_in_overflow.c
+++ b/3rdparty/portaudio/test/patest_in_overflow.c
diff --git a/portaudio/test/patest_jack_wasapi.c b/3rdparty/portaudio/test/patest_jack_wasapi.c
index bd79881..bd79881 100644
--- a/portaudio/test/patest_jack_wasapi.c
+++ b/3rdparty/portaudio/test/patest_jack_wasapi.c
diff --git a/portaudio/test/patest_latency.c b/3rdparty/portaudio/test/patest_latency.c
index 7f622c1..7f622c1 100644
--- a/portaudio/test/patest_latency.c
+++ b/3rdparty/portaudio/test/patest_latency.c
diff --git a/portaudio/test/patest_leftright.c b/3rdparty/portaudio/test/patest_leftright.c
index e61a351..e61a351 100644
--- a/portaudio/test/patest_leftright.c
+++ b/3rdparty/portaudio/test/patest_leftright.c
diff --git a/portaudio/test/patest_longsine.c b/3rdparty/portaudio/test/patest_longsine.c
index f439030..f439030 100644
--- a/portaudio/test/patest_longsine.c
+++ b/3rdparty/portaudio/test/patest_longsine.c
diff --git a/portaudio/test/patest_many.c b/3rdparty/portaudio/test/patest_many.c
index 76cc043..76cc043 100644
--- a/portaudio/test/patest_many.c
+++ b/3rdparty/portaudio/test/patest_many.c
diff --git a/portaudio/test/patest_maxsines.c b/3rdparty/portaudio/test/patest_maxsines.c
index 638a01a..638a01a 100644
--- a/portaudio/test/patest_maxsines.c
+++ b/3rdparty/portaudio/test/patest_maxsines.c
diff --git a/portaudio/test/patest_mono.c b/3rdparty/portaudio/test/patest_mono.c
index e7d7d1b..e7d7d1b 100644
--- a/portaudio/test/patest_mono.c
+++ b/3rdparty/portaudio/test/patest_mono.c
diff --git a/portaudio/test/patest_multi_sine.c b/3rdparty/portaudio/test/patest_multi_sine.c
index ec9ed8c..ec9ed8c 100644
--- a/portaudio/test/patest_multi_sine.c
+++ b/3rdparty/portaudio/test/patest_multi_sine.c
diff --git a/portaudio/test/patest_out_underflow.c b/3rdparty/portaudio/test/patest_out_underflow.c
index a8c45ea..a8c45ea 100644
--- a/portaudio/test/patest_out_underflow.c
+++ b/3rdparty/portaudio/test/patest_out_underflow.c
diff --git a/portaudio/test/patest_prime.c b/3rdparty/portaudio/test/patest_prime.c
index e943310..e943310 100644
--- a/portaudio/test/patest_prime.c
+++ b/3rdparty/portaudio/test/patest_prime.c
diff --git a/portaudio/test/patest_read_record.c b/3rdparty/portaudio/test/patest_read_record.c
index bd9c7fe..bd9c7fe 100644
--- a/portaudio/test/patest_read_record.c
+++ b/3rdparty/portaudio/test/patest_read_record.c
diff --git a/portaudio/test/patest_ringmix.c b/3rdparty/portaudio/test/patest_ringmix.c
index 2db6706..2db6706 100644
--- a/portaudio/test/patest_ringmix.c
+++ b/3rdparty/portaudio/test/patest_ringmix.c
diff --git a/portaudio/test/patest_sine8.c b/3rdparty/portaudio/test/patest_sine8.c
index 82de69d..82de69d 100644
--- a/portaudio/test/patest_sine8.c
+++ b/3rdparty/portaudio/test/patest_sine8.c
diff --git a/portaudio/test/patest_sine_channelmaps.c b/3rdparty/portaudio/test/patest_sine_channelmaps.c
index 3476701..3476701 100644
--- a/portaudio/test/patest_sine_channelmaps.c
+++ b/3rdparty/portaudio/test/patest_sine_channelmaps.c
diff --git a/portaudio/test/patest_sine_formats.c b/3rdparty/portaudio/test/patest_sine_formats.c
index 3224d6e..3224d6e 100644
--- a/portaudio/test/patest_sine_formats.c
+++ b/3rdparty/portaudio/test/patest_sine_formats.c
diff --git a/portaudio/test/patest_sine_srate.c b/3rdparty/portaudio/test/patest_sine_srate.c
index d4ce81b..d4ce81b 100644
--- a/portaudio/test/patest_sine_srate.c
+++ b/3rdparty/portaudio/test/patest_sine_srate.c
diff --git a/portaudio/test/patest_sine_time.c b/3rdparty/portaudio/test/patest_sine_time.c
index c1d6097..c1d6097 100644
--- a/portaudio/test/patest_sine_time.c
+++ b/3rdparty/portaudio/test/patest_sine_time.c
diff --git a/portaudio/test/patest_start_stop.c b/3rdparty/portaudio/test/patest_start_stop.c
index 2470b26..2470b26 100644
--- a/portaudio/test/patest_start_stop.c
+++ b/3rdparty/portaudio/test/patest_start_stop.c
diff --git a/portaudio/test/patest_stop.c b/3rdparty/portaudio/test/patest_stop.c
index 164ad4e..164ad4e 100644
--- a/portaudio/test/patest_stop.c
+++ b/3rdparty/portaudio/test/patest_stop.c
diff --git a/portaudio/test/patest_stop_playout.c b/3rdparty/portaudio/test/patest_stop_playout.c
index 7e6932e..7e6932e 100644
--- a/portaudio/test/patest_stop_playout.c
+++ b/3rdparty/portaudio/test/patest_stop_playout.c
diff --git a/portaudio/test/patest_suggested_vs_streaminfo_latency.c b/3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.c
index c26d871..c26d871 100644
--- a/portaudio/test/patest_suggested_vs_streaminfo_latency.c
+++ b/3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.c
diff --git a/portaudio/test/patest_suggested_vs_streaminfo_latency.py b/3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.py
index 8026787..8026787 100644
--- a/portaudio/test/patest_suggested_vs_streaminfo_latency.py
+++ b/3rdparty/portaudio/test/patest_suggested_vs_streaminfo_latency.py
diff --git a/portaudio/test/patest_sync.c b/3rdparty/portaudio/test/patest_sync.c
index 52df0fe..52df0fe 100644
--- a/portaudio/test/patest_sync.c
+++ b/3rdparty/portaudio/test/patest_sync.c
diff --git a/portaudio/test/patest_timing.c b/3rdparty/portaudio/test/patest_timing.c
index 2a240b4..2a240b4 100644
--- a/portaudio/test/patest_timing.c
+++ b/3rdparty/portaudio/test/patest_timing.c
diff --git a/portaudio/test/patest_toomanysines.c b/3rdparty/portaudio/test/patest_toomanysines.c
index 2d32071..2d32071 100644
--- a/portaudio/test/patest_toomanysines.c
+++ b/3rdparty/portaudio/test/patest_toomanysines.c
diff --git a/portaudio/test/patest_two_rates.c b/3rdparty/portaudio/test/patest_two_rates.c
index 2116b1e..2116b1e 100644
--- a/portaudio/test/patest_two_rates.c
+++ b/3rdparty/portaudio/test/patest_two_rates.c
diff --git a/portaudio/test/patest_underflow.c b/3rdparty/portaudio/test/patest_underflow.c
index 96216a6..96216a6 100644
--- a/portaudio/test/patest_underflow.c
+++ b/3rdparty/portaudio/test/patest_underflow.c
diff --git a/portaudio/test/patest_unplug.c b/3rdparty/portaudio/test/patest_unplug.c
index 0e4486e..0e4486e 100644
--- a/portaudio/test/patest_unplug.c
+++ b/3rdparty/portaudio/test/patest_unplug.c
diff --git a/portaudio/test/patest_wire.c b/3rdparty/portaudio/test/patest_wire.c
index f04e6be..f04e6be 100644
--- a/portaudio/test/patest_wire.c
+++ b/3rdparty/portaudio/test/patest_wire.c
diff --git a/portaudio/test/patest_wmme_find_best_latency_params.c b/3rdparty/portaudio/test/patest_wmme_find_best_latency_params.c
index 5c715f9..5c715f9 100644
--- a/portaudio/test/patest_wmme_find_best_latency_params.c
+++ b/3rdparty/portaudio/test/patest_wmme_find_best_latency_params.c
diff --git a/portaudio/test/patest_wmme_low_level_latency_params.c b/3rdparty/portaudio/test/patest_wmme_low_level_latency_params.c
index 31c8892..31c8892 100644
--- a/portaudio/test/patest_wmme_low_level_latency_params.c
+++ b/3rdparty/portaudio/test/patest_wmme_low_level_latency_params.c
diff --git a/portaudio/test/patest_write_stop.c b/3rdparty/portaudio/test/patest_write_stop.c
index 855923f..855923f 100644
--- a/portaudio/test/patest_write_stop.c
+++ b/3rdparty/portaudio/test/patest_write_stop.c
diff --git a/portaudio/test/patest_write_stop_hang_illegal.c b/3rdparty/portaudio/test/patest_write_stop_hang_illegal.c
index 3d53d4f..3d53d4f 100644
--- a/portaudio/test/patest_write_stop_hang_illegal.c
+++ b/3rdparty/portaudio/test/patest_write_stop_hang_illegal.c
diff --git a/portaudio/update_gitrevision.sh b/3rdparty/portaudio/update_gitrevision.sh
index 80d4f3b..80d4f3b 100755
--- a/portaudio/update_gitrevision.sh
+++ b/3rdparty/portaudio/update_gitrevision.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b51a63f..c631e11 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,25 +7,32 @@ project(
include_directories(${CMAKE_SOURCE_DIR}/include)
option(MOSSROSE_BUILD_EXAMPLES "Build the example programs" OFF)
+option(MOSSROSE_BUILD_TESTS "Build the tests" OFF)
-add_subdirectory(${CMAKE_SOURCE_DIR}/portaudio EXCLUDE_FROM_ALL)
+######## third-party libraries ########
+add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/portaudio EXCLUDE_FROM_ALL)
+add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/plibsys EXCLUDE_FROM_ALL)
add_library(mossrose)
-add_subdirectory(${CMAKE_SOURCE_DIR}/src)
set_target_properties(mossrose PROPERTIES
C_STANDARD 99
CMAKE_C_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wpedantic"
VERSION ${PROJECT_VERSION}
PUBLIC_HEADER src/mossrose.h
)
-target_link_libraries(mossrose portaudio)
-if (UNIX)
- target_link_libraries(mossrose pthread)
-endif()
+target_link_libraries(mossrose portaudio plibsys)
if (MOSSROSE_BUILD_EXAMPLES)
add_custom_target(examples)
add_subdirectory(${CMAKE_SOURCE_DIR}/examples)
endif()
+
+
+if (MOSSROSE_BUILD_TESTS)
+ add_executable(test)
+endif()
+
+
+add_subdirectory(${CMAKE_SOURCE_DIR}/src)
diff --git a/portaudio/bindings/cpp/build/gnu/Makefile.in b/portaudio/bindings/cpp/build/gnu/Makefile.in
deleted file mode 100644
index 0bc6f28..0000000
--- a/portaudio/bindings/cpp/build/gnu/Makefile.in
+++ /dev/null
@@ -1,106 +0,0 @@
-#
-# Makefile template for PortAudioCpp
-# Ludwig Schwardt
-# 01/10/2003
-#
-# Not much to edit here - rather check configure.ac
-#
-
-PREFIX = @prefix@
-CC = @CC@
-CXX = @CXX@
-CFLAGS = @CFLAGS@ @DEFS@
-CXXFLAGS = @CXXFLAGS@
-SHARED_FLAGS = @SHARED_FLAGS@
-LIBS = @LIBS@
-DLL_LIBS = @DLL_LIBS@
-AR = @AR@
-RANLIB = @RANLIB@
-INSTALL = @INSTALL@
-
-PACPP_ROOT = @PACPP_ROOT@
-PORTAUDIO = @PORTAUDIO@
-PADLL = @PADLL@
-PACPP_DLL = @PACPP_DLL@
-PALIB = libportaudio.a
-PACPP_LIB = libportaudiocpp.a
-PACPP_DLLV = $(PACPP_DLL).0.0.12
-
-SRCDIR = $(PACPP_ROOT)/source/portaudiocpp
-BINDIR = $(PACPP_ROOT)/example
-LIBDIR = $(PACPP_ROOT)/lib
-DOCDIR = $(PACPP_ROOT)/doc
-
-OBJS = \
- $(SRCDIR)/BlockingStream.o \
- $(SRCDIR)/CallbackInterface.o \
- $(SRCDIR)/CallbackStream.o \
- $(SRCDIR)/CFunCallbackStream.o \
- $(SRCDIR)/CppFunCallbackStream.o \
- $(SRCDIR)/Device.o \
- $(SRCDIR)/DirectionSpecificStreamParameters.o \
- $(SRCDIR)/Exception.o \
- $(SRCDIR)/HostApi.o \
- $(SRCDIR)/InterfaceCallbackStream.o \
- $(SRCDIR)/MemFunCallbackStream.o \
- $(SRCDIR)/Stream.o \
- $(SRCDIR)/StreamParameters.o \
- $(SRCDIR)/System.o \
- $(SRCDIR)/SystemDeviceIterator.o \
- $(SRCDIR)/SystemHostApiIterator.o
-
-# Not supported yet
-# $(SRCDIR)/AsioDeviceAdapter.o
-
-EXAMPLES = \
- $(BINDIR)/devs \
- $(BINDIR)/sine
-
-.PHONY: all clean docs
-
-all: $(EXAMPLES) $(LIBDIR)/$(PACPP_LIB) $(LIBDIR)/$(PACPP_DLL)
-
-clean:
- rm -rf $(SRCDIR)/*.o $(BINDIR)/*.o $(EXAMPLES) $(LIBDIR) $(DOCDIR)/api_reference
- rm -rf autom4te.cache config.status config.log
-
-docs:
- cd $(DOCDIR); doxygen config.doxy.linux
-
-%.o: %.c
- $(CC) -c $(CFLAGS) $< -o $@
-
-%.o: %.cxx
- $(CXX) -c $(CXXFLAGS) $< -o $@
-
-
-$(EXAMPLES): $(BINDIR)/%: $(BINDIR)/%.o $(OBJS)
- $(CXX) $^ -o $@ $(LIBS)
-
-$(LIBDIR)/$(PACPP_LIB): $(LIBDIR) $(OBJS)
- $(AR) ruv $(LIBDIR)/$(PACPP_LIB) $(OBJS)
- $(RANLIB) $(LIBDIR)/$(PACPP_LIB)
-
-$(LIBDIR)/$(PACPP_DLLV): $(LIBDIR) $(OBJS)
- $(CXX) $(SHARED_FLAGS) -o $(LIBDIR)/$(PACPP_DLLV) $(OBJS) $(DLL_LIBS)
-
-$(LIBDIR)/$(PACPP_DLL): $(LIBDIR) $(OBJS)
- $(CXX) $(SHARED_FLAGS) -o $(LIBDIR)/$(PACPP_DLL) $(OBJS) $(DLL_LIBS)
-
-#install: $(LIBDIR)/$(PACPP_LIB) $(LIBDIR)/$(PACPP_DLLV)
-# $(INSTALL) -m 644 $(LIBDIR)/$(PACPP_DLLV) $(PREFIX)/lib/$(PACPP_DLLV)
-# $(INSTALL) -m 644 $(LIBDIR)/$(PACPP_LIB) $(PREFIX)/lib/$(PACPP_LIB)
-# cd $(PREFIX)/lib && rm -f $(PACPP_DLL) && ln -s $(PACPP_DLLV) $(PACPP_DLL)
-# @echo ""
-# @echo "------------------------------------------------------------"
-# @echo "PortAudioCpp was successfully installed."
-# @echo ""
-# @echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
-# @echo "to make the shared object available. You may also need to"
-# @echo "modify your LD_LIBRARY_PATH environment variable to include"
-# @echo "the directory $(PREFIX)/lib"
-# @echo "------------------------------------------------------------"
-# @echo ""
-
-$(LIBDIR):
- mkdir $(LIBDIR)
diff --git a/portaudio/bindings/cpp/build/gnu/OUT_OF_DATE b/portaudio/bindings/cpp/build/gnu/OUT_OF_DATE
deleted file mode 100644
index e69de29..0000000
--- a/portaudio/bindings/cpp/build/gnu/OUT_OF_DATE
+++ /dev/null
diff --git a/portaudio/bindings/cpp/build/gnu/aclocal.m4 b/portaudio/bindings/cpp/build/gnu/aclocal.m4
deleted file mode 100644
index c80e0ac..0000000
--- a/portaudio/bindings/cpp/build/gnu/aclocal.m4
+++ /dev/null
@@ -1,57 +0,0 @@
-
-dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
-dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
-dnl also defines GSTUFF_PKG_ERRORS on error
-AC_DEFUN(PKG_CHECK_MODULES, [
- succeeded=no
-
- if test -z "$PKG_CONFIG"; then
- AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
- fi
-
- if test "$PKG_CONFIG" = "no" ; then
- echo "*** The pkg-config script could not be found. Make sure it is"
- echo "*** in your path, or set the PKG_CONFIG environment variable"
- echo "*** to the full path to pkg-config."
- echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
- else
- PKG_CONFIG_MIN_VERSION=0.9.0
- if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
- AC_MSG_CHECKING(for $2)
-
- if $PKG_CONFIG --exists "$2" ; then
- AC_MSG_RESULT(yes)
- succeeded=yes
-
- AC_MSG_CHECKING($1_CFLAGS)
- $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
- AC_MSG_RESULT($$1_CFLAGS)
-
- AC_MSG_CHECKING($1_LIBS)
- $1_LIBS=`$PKG_CONFIG --libs "$2"`
- AC_MSG_RESULT($$1_LIBS)
- else
- $1_CFLAGS=""
- $1_LIBS=""
- ## If we have a custom action on failure, don't print errors, but
- ## do set a variable so people can do so.
- $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
- ifelse([$4], ,echo $$1_PKG_ERRORS,)
- fi
-
- AC_SUBST($1_CFLAGS)
- AC_SUBST($1_LIBS)
- else
- echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
- echo "*** See http://www.freedesktop.org/software/pkgconfig"
- fi
- fi
-
- if test $succeeded = yes; then
- ifelse([$3], , :, [$3])
- else
- ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
- fi
-])
-
-
diff --git a/portaudio/bindings/cpp/build/gnu/config.guess b/portaudio/bindings/cpp/build/gnu/config.guess
deleted file mode 100644
index d5128ac..0000000
--- a/portaudio/bindings/cpp/build/gnu/config.guess
+++ /dev/null
@@ -1,1308 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-
-timestamp='2001-10-05'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script.
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int dummy(){}" > $dummy.c ;
- for c in cc gcc c89 ; do
- ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
- if test $? = 0 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- rm -f $dummy.c $dummy.o $dummy.rel ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- # Determine the machine/vendor (is the vendor relevant).
- case "${UNAME_MACHINE}" in
- amiga) machine=m68k-unknown ;;
- arm32) machine=arm-unknown ;;
- atari*) machine=m68k-atari ;;
- sun3*) machine=m68k-sun ;;
- mac68k) machine=m68k-apple ;;
- macppc) machine=powerpc-apple ;;
- hp3[0-9][05]) machine=m68k-hp ;;
- ibmrt|romp-ibm) machine=romp-ibm ;;
- sparc*) machine=`uname -p`-unknown ;;
- *) machine=${UNAME_MACHINE}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE}" in
- i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit 0 ;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- macppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvmeppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mipseb-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- case `./$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- esac
- fi
- rm -f $dummy.s $dummy
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit 0 ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit 0 ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit 0 ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit 0;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit 0 ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit 0 ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit 0 ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit 0 ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit 0 ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit 0 ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy \
- && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit 0 ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit 0 ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
- if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
- rm -f $dummy.c $dummy
- fi ;;
- esac
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit 0 ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:*:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3D:*:*:*)
- echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY-2:*:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit 0 ;;
- i*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit 0 ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit 0 ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i386-pc-interix
- exit 0 ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit 0 ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit 0 ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- *:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit 0 ;;
- arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
- exit 0 ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- mips:Linux:*:*)
- case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
- big) echo mips-unknown-linux-gnu && exit 0 ;;
- little) echo mipsel-unknown-linux-gnu && exit 0 ;;
- esac
- ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit 0 ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit 0 ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit 0 ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit 0 ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit 0 ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit 0 ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit 0 ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- ld_supported_targets=`cd /; ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0 ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit 0 ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit 0 ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-# if __GLIBC__ >= 2
- printf ("%s-pc-linux-gnu\n", argv[1]);
-# else
- printf ("%s-pc-linux-gnulibc1\n", argv[1]);
-# endif
-# else
- printf ("%s-pc-linux-gnulibc1\n", argv[1]);
-# endif
-#else
- printf ("%s-pc-linux-gnuaout\n", argv[1]);
-#endif
- return 0;
-}
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit 0 ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit 0 ;;
- i*86:*:5:[78]*)
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit 0 ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit 0 ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- M68*:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit 0 ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit 0 ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit 0 ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit 0 ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit 0 ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit 0 ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit 0 ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit 0 ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Darwin:*:*)
- echo `uname -p`-apple-darwin${UNAME_RELEASE}
- exit 0 ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- if test "${UNAME_MACHINE}" = "x86pc"; then
- UNAME_MACHINE=pc
- fi
- echo `uname -p`-${UNAME_MACHINE}-nto-qnx
- exit 0 ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit 0 ;;
- NSR-[KW]:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit 0 ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit 0 ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit 0 ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit 0 ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit 0 ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit 0 ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit 0 ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit 0 ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit 0 ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit 0 ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit 0 ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit 0 ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- ftp://ftp.gnu.org/pub/gnu/config/
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/portaudio/bindings/cpp/build/gnu/config.sub b/portaudio/bindings/cpp/build/gnu/config.sub
deleted file mode 100644
index 6eea727..0000000
--- a/portaudio/bindings/cpp/build/gnu/config.sub
+++ /dev/null
@@ -1,1505 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-
-timestamp='2003-07-17'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit 0;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | m32r | m68000 | m68k | m88k | mcore \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | msp430 \
- | ns16k | ns32k \
- | openrisc | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
- | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
- | we32k \
- | x86 | xscale | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* \
- | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | m32r-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | msp430-* \
- | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
- | xtensa-* \
- | ymp-* \
- | z8k-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- mmix*)
- basic_machine=mmix-knuth
- os=-mmixware
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nv1)
- basic_machine=nv1-cray
- os=-unicosmp
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- or32 | or32-*)
- basic_machine=or32-unknown
- os=-coff
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparc | sparcv9 | sparcv9b)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-ibm)
- os=-aix
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/portaudio/bindings/cpp/build/gnu/configure b/portaudio/bindings/cpp/build/gnu/configure
deleted file mode 100644
index 69070c6..0000000
--- a/portaudio/bindings/cpp/build/gnu/configure
+++ /dev/null
@@ -1,4297 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.57 for PortAudioCpp 12.
-#
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
-fi
-
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
- sed '
- N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
- t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
- ' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
- # Exit status is that of the last command.
- exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
- else
- as_ln_s='ln -s'
- fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-exec 6>&1
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_config_libobj_dir=.
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete. It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
-
-# Identity of this package.
-PACKAGE_NAME='PortAudioCpp'
-PACKAGE_TARNAME='portaudiocpp'
-PACKAGE_VERSION='12'
-PACKAGE_STRING='PortAudioCpp 12'
-PACKAGE_BUGREPORT=''
-
-ac_unique_file="../../include/portaudiocpp/PortAudioCpp.hxx"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX LN_S RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR PACPP_ROOT PORTAUDIO PADLL PACPP_DLL PACPP_INC SHARED_FLAGS DLL_LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os PKG_CONFIG JACK_CFLAGS JACK_LIBS LIBOBJS LTLIBOBJS'
-ac_subst_files=''
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-ac_prev=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_option in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- eval "enable_$ac_feature=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_$ac_feature='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
- *) ac_optarg=yes ;;
- esac
- eval "with_$ac_package='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/-/_/g'`
- eval "with_$ac_package=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
- eval "$ac_envvar='$ac_optarg'"
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
-fi
-
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
-do
- eval ac_val=$`echo $ac_var`
- case $ac_val in
- [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
- esac
-done
-
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
-do
- eval ac_val=$`echo $ac_var`
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
- esac
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_confdir=`(dirname "$0") 2>/dev/null ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
- { (exit 1); exit 1; }; }
- else
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); exit 1; }; }
- fi
-fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
- { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
- { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CXX_set=${CXX+set}
-ac_env_CXX_value=$CXX
-ac_cv_env_CXX_set=${CXX+set}
-ac_cv_env_CXX_value=$CXX
-ac_env_CXXFLAGS_set=${CXXFLAGS+set}
-ac_env_CXXFLAGS_value=$CXXFLAGS
-ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
-ac_cv_env_CXXFLAGS_value=$CXXFLAGS
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures PortAudioCpp 12 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-_ACEOF
-
- cat <<_ACEOF
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --infodir=DIR info documentation [PREFIX/info]
- --mandir=DIR man documentation [PREFIX/man]
-_ACEOF
-
- cat <<\_ACEOF
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of PortAudioCpp 12:";;
- esac
- cat <<\_ACEOF
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-alsa (default=auto)
- --with-jack (default=auto)
- --with-oss (default=yes)
- --with-host_os (no default)
- --with-winapi ((wmme/directx/asio) default=wmme)
- --with-macapi (asio) default=asio)
- --with-asiodir (default=/usr/local/asiosdk2)
- --with-dxdir (default=/usr/local/dx7sdk)
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
- headers in a nonstandard directory <include dir>
- CXX C++ compiler command
- CXXFLAGS C++ compiler flags
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-_ACEOF
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- ac_popdir=`pwd`
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d $ac_dir || continue
- ac_builddir=.
-
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
- .) # No --srcdir option. We are building in place.
- ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
-
- cd $ac_dir
- # Check for guested configure; otherwise get Cygnus style configure.
- if test -f $ac_srcdir/configure.gnu; then
- echo
- $SHELL $ac_srcdir/configure.gnu --help=recursive
- elif test -f $ac_srcdir/configure; then
- echo
- $SHELL $ac_srcdir/configure --help=recursive
- elif test -f $ac_srcdir/configure.ac ||
- test -f $ac_srcdir/configure.in; then
- echo
- $ac_configure --help
- else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi
- cd "$ac_popdir"
- done
-fi
-
-test -n "$ac_init_help" && exit 0
-if $ac_init_version; then
- cat <<\_ACEOF
-PortAudioCpp configure 12
-generated by GNU Autoconf 2.57
-
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit 0
-fi
-exec 5>config.log
-cat >&5 <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by PortAudioCpp $as_me 12, which was
-generated by GNU Autoconf 2.57. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_sep=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
- 2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
- # Get rid of the leading space.
- ac_sep=" "
- ;;
- esac
- done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-{
- (set) 2>&1 |
- case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- sed -n \
- "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
- ;;
- *)
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
- ;;
- esac;
-}
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- sed "/^$/d" confdefs.h | sort
- echo
- fi
- test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core &&
- rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
- ' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . $cache_file;;
- *) . ./$cache_file;;
- esac
- fi
-else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
- sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val="\$ac_cv_env_${ac_var}_value"
- eval ac_new_val="\$ac_env_${ac_var}_value"
- case $ac_old_set,$ac_new_set in
- set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-###### Top-level directory of pacpp
-###### This makes it easy to shuffle the build directories
-###### Also edit AC_CONFIG_SRCDIR above (wouldn't accept this variable)!
-PACPP_ROOT="../.."
-
-######
-###### SET THIS TO PORTAUDIO DIRECTORY
-######
-PORTAUDIO="$PACPP_ROOT/../portaudio"
-
-# Various other variables and flags
-
-PACPP_INC="$PACPP_ROOT/include"
-INCLUDES="-I$PACPP_INC -I$PORTAUDIO -I$PORTAUDIO/pa_common"
-CFLAGS="-g -O2 -Wall -ansi -pedantic $INCLUDES"
-CXXFLAGS="$CFLAGS"
-PALIBDIR="$PORTAUDIO/lib"
-
-# Checks for programs
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$ac_ct_CC" && break
-done
-
- CC=$ac_ct_CC
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output" >&5
-echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Find the output, starting from the most likely. This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
- conftest.$ac_ext )
- # This is the source file.
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
- break;;
- * )
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
- fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
- break;;
- * ) break;;
- esac
-done
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
- *)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C. Since we use `exit',
-# in C++ we need to declare it. In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
- choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
-fi
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=cc
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CXX="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$ac_ct_CXX" && break
-done
-test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
-
- CXX=$ac_ct_CXX
-fi
-
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C++ compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
-GXX=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-CXXFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
-echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cxx_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cxx_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cxx_g=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
- echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- RANLIB=$ac_ct_RANLIB
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f $ac_dir/shtool; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
-echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
- { (exit 1); exit 1; }; }
-fi
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"
-ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in
- ./ | .// | /cC/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- done
- done
- ;;
-esac
-done
-
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. We don't cache a
- # path for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the path is relative.
- INSTALL=$ac_install_sh
- fi
-fi
-echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-# Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $AR in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_AR="$AR" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- test -z "$ac_cv_path_AR" && ac_cv_path_AR="no"
- ;;
-esac
-fi
-AR=$ac_cv_path_AR
-
-if test -n "$AR"; then
- echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-if [ $AR = "no" ] ; then
- { { echo "$as_me:$LINENO: error: \"Could not find ar - needed to create a library\"" >&5
-echo "$as_me: error: \"Could not find ar - needed to create a library\"" >&2;}
- { (exit 1); exit 1; }; };
-fi
-
-# This must be one of the first tests we do or it will fail...
-
-echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
-echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
-if test "${ac_cv_c_bigendian+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # See if sys/param.h defines the BYTE_ORDER macro.
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/param.h>
-
-int
-main ()
-{
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- # It does; now see whether it defined to BIG_ENDIAN or not.
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/param.h>
-
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_bigendian=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_c_bigendian=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-# It does not; compile a test program.
-if test "$cross_compiling" = yes; then
- # try to guess the endianness by grepping values into an object file
- ac_cv_c_bigendian=unknown
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
-short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
-int
-main ()
-{
- _ascii (); _ebcdic ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
- ac_cv_c_bigendian=yes
-fi
-if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
- if test "$ac_cv_c_bigendian" = unknown; then
- ac_cv_c_bigendian=no
- else
- # finding both strings is unlikely to happen, but who knows?
- ac_cv_c_bigendian=unknown
- fi
-fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-int
-main ()
-{
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long l;
- char c[sizeof (long)];
- } u;
- u.l = 1;
- exit (u.c[sizeof (long) - 1] == 1);
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_bigendian=no
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_bigendian=yes
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
-echo "${ECHO_T}$ac_cv_c_bigendian" >&6
-case $ac_cv_c_bigendian in
- yes)
-
-cat >>confdefs.h <<\_ACEOF
-#define WORDS_BIGENDIAN 1
-_ACEOF
- ;;
- no)
- ;;
- *)
- { { echo "$as_me:$LINENO: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&5
-echo "$as_me: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
- { (exit 1); exit 1; }; } ;;
-esac
-
-
-# Transfer these variables to the Makefile
-
-
-
-
-
-
-
-
-
-##################### CHECK FOR INSTALLED PACKAGES ############################
-
-# checks for various host APIs and arguments to configure that
-# turn them on or off
-
-echo "$as_me:$LINENO: checking for snd_pcm_open in -lasound" >&5
-echo $ECHO_N "checking for snd_pcm_open in -lasound... $ECHO_C" >&6
-if test "${ac_cv_lib_asound_snd_pcm_open+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lasound $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char snd_pcm_open ();
-int
-main ()
-{
-snd_pcm_open ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_asound_snd_pcm_open=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_asound_snd_pcm_open=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_pcm_open" >&5
-echo "${ECHO_T}$ac_cv_lib_asound_snd_pcm_open" >&6
-if test $ac_cv_lib_asound_snd_pcm_open = yes; then
- have_alsa=yes
-else
- have_alsa=no
-fi
-
-
-# Determine the host description for the subsequent test.
-# PKG_CHECK_MODULES seems to check and set the host variable also, but
-# that then requires pkg-config availability which is not standard on
-# MinGW systems and can be a pain to install.
-# Make sure we can run config.sub.
-$ac_config_sub sun4 >/dev/null 2>&1 ||
- { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
-echo "$as_me: error: cannot run $ac_config_sub" >&2;}
- { (exit 1); exit 1; }; }
-
-echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6
-if test "${ac_cv_build+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_build_alias=$build_alias
-test -z "$ac_cv_build_alias" &&
- ac_cv_build_alias=`$ac_config_guess`
-test -z "$ac_cv_build_alias" &&
- { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
- { (exit 1); exit 1; }; }
-ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
- { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6
-build=$ac_cv_build
-build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6
-if test "${ac_cv_host+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_host_alias=$host_alias
-test -z "$ac_cv_host_alias" &&
- ac_cv_host_alias=$ac_cv_build_alias
-ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
- { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6
-host=$ac_cv_host
-host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-
-
- succeeded=no
-
- if test -z "$PKG_CONFIG"; then
- # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PKG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
- ;;
-esac
-fi
-PKG_CONFIG=$ac_cv_path_PKG_CONFIG
-
-if test -n "$PKG_CONFIG"; then
- echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
-echo "${ECHO_T}$PKG_CONFIG" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- fi
-
- if test "$PKG_CONFIG" = "no" ; then
- echo "*** The pkg-config script could not be found. Make sure it is"
- echo "*** in your path, or set the PKG_CONFIG environment variable"
- echo "*** to the full path to pkg-config."
- echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
- else
- PKG_CONFIG_MIN_VERSION=0.9.0
- if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
- echo "$as_me:$LINENO: checking for jack" >&5
-echo $ECHO_N "checking for jack... $ECHO_C" >&6
-
- if $PKG_CONFIG --exists "jack" ; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- succeeded=yes
-
- echo "$as_me:$LINENO: checking JACK_CFLAGS" >&5
-echo $ECHO_N "checking JACK_CFLAGS... $ECHO_C" >&6
- JACK_CFLAGS=`$PKG_CONFIG --cflags "jack"`
- echo "$as_me:$LINENO: result: $JACK_CFLAGS" >&5
-echo "${ECHO_T}$JACK_CFLAGS" >&6
-
- echo "$as_me:$LINENO: checking JACK_LIBS" >&5
-echo $ECHO_N "checking JACK_LIBS... $ECHO_C" >&6
- JACK_LIBS=`$PKG_CONFIG --libs "jack"`
- echo "$as_me:$LINENO: result: $JACK_LIBS" >&5
-echo "${ECHO_T}$JACK_LIBS" >&6
- else
- JACK_CFLAGS=""
- JACK_LIBS=""
- ## If we have a custom action on failure, don't print errors, but
- ## do set a variable so people can do so.
- JACK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "jack"`
-
- fi
-
-
-
- else
- echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
- echo "*** See http://www.freedesktop.org/software/pkgconfig"
- fi
- fi
-
- if test $succeeded = yes; then
- have_jack=yes
- else
- have_jack=no
- fi
-
-
-
-# Check whether --with-alsa or --without-alsa was given.
-if test "${with_alsa+set}" = set; then
- withval="$with_alsa"
- with_alsa=$withval
-else
- with_alsa="yes"
-fi;
-
-
-# Check whether --with-jack or --without-jack was given.
-if test "${with_jack+set}" = set; then
- withval="$with_jack"
- with_jack=$withval
-else
- with_jack="yes"
-fi;
-
-
-# Check whether --with-oss or --without-oss was given.
-if test "${with_oss+set}" = set; then
- withval="$with_oss"
- with_oss=$withval
-else
- with_oss="yes"
-fi;
-
-
-# Check whether --with-host_os or --without-host_os was given.
-if test "${with_host_os+set}" = set; then
- withval="$with_host_os"
- host_os=$withval
-fi;
-
-
-# Check whether --with-winapi or --without-winapi was given.
-if test "${with_winapi+set}" = set; then
- withval="$with_winapi"
- with_winapi=$withval
-else
- with_winapi="wmme"
-fi;
-
-# Mac API added for ASIO, can have other api's listed
-
-# Check whether --with-macapi or --without-macapi was given.
-if test "${with_macapi+set}" = set; then
- withval="$with_macapi"
- with_macapi=$withval
-else
- with_macapi="asio"
-fi;
-
-
-# Check whether --with-asiodir or --without-asiodir was given.
-if test "${with_asiodir+set}" = set; then
- withval="$with_asiodir"
- with_asiodir=$withval
-else
- with_asiodir="/usr/local/asiosdk2"
-fi;
-
-
-# Check whether --with-dxdir or --without-dxdir was given.
-if test "${with_dxdir+set}" = set; then
- withval="$with_dxdir"
- with_dxdir=$withval
-else
- with_dxdir="/usr/local/dx7sdk"
-fi;
-
-
-##################### HOST-SPECIFIC LIBRARY SETTINGS ##########################
-
-case "${host_os}" in
- darwin* )
- # Mac OS X configuration
-
- LIBS="-framework AudioUnit -framework AudioToolbox -framework CoreAudio";
- PADLL="libportaudio.dylib";
- PACPP_DLL="libportaudiocpp.dylib";
- SHARED_FLAGS="-framework AudioUnit -framework AudioToolbox";
- SHARED_FLAGS="$SHARED_FLAGS -framework CoreAudio -dynamiclib";
- if [ $with_macapi = "asio" ] ; then
- if [ $with_asiodir ] ; then
- ASIODIR="$with_asiodir";
- else
- ASIODIR="/usr/local/asiosdk2";
- fi
- echo "ASIODIR: $ASIODIR";
- fi
- ;;
-
- mingw* )
- # MingW configuration
-
- echo "WINAPI: $with_winapi"
- if [ $with_winapi = "directx" ] ; then
- if [ $with_dxdir ] ; then
- DXDIR="$with_dxdir";
- else
- DXDIR="/usr/local/dx7sdk";
- fi
- echo "DXDIR: $DXDIR"
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -ldsound -lole32";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm -lm -L./dx7sdk/lib -ldsound -lole32";
- CFLAGS="$CFLAGS -DPA_NO_WMME -DPA_NO_ASIO";
- CXXFLAGS="$CFLAGS"
- elif [ $with_winapi = "asio" ] ; then
- if [ $with_asiodir ] ; then
- ASIODIR="$with_asiodir";
- else
- ASIODIR="/usr/local/asiosdk2";
- fi
- echo "ASIODIR: $ASIODIR"
-
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -lstdc++ -lole32 -luuid";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
- CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -DPA_NO_WMME -DPA_NO_DS -DWINDOWS";
- CXXFLAGS="$CFLAGS";
- else # WMME default
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -lstdc++ -lole32 -luuid";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm";
- CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_ASIO";
- CXXFLAGS="$CFLAGS";
- fi
- ;;
-
- cygwin* )
- # Cygwin configuration
-
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm";
- ;;
-
- *)
- # Unix OSS configuration
-
-
-echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
-echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6
-if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char pthread_create ();
-int
-main ()
-{
-pthread_create ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_pthread_pthread_create=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_pthread_pthread_create=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
-echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6
-if test $ac_cv_lib_pthread_pthread_create = yes; then
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBPTHREAD 1
-_ACEOF
-
- LIBS="-lpthread $LIBS"
-
-else
- { { echo "$as_me:$LINENO: error: libpthread not found!" >&5
-echo "$as_me: error: libpthread not found!" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
- LIBS="$LIBS -L$PALIBDIR -lportaudio"
-
- if [ $have_jack = "yes" ] && [ $with_jack != "no" ] ; then
- LIBS="$LIBS $JACK_LIBS"
- CFLAGS="$CFLAGS $JACK_CFLAGS"
- cat >>confdefs.h <<\_ACEOF
-#define PA_USE_JACK 1
-_ACEOF
-
- fi
-
- if [ $have_alsa = "yes" ] && [ $with_alsa != "no" ] ; then
- LIBS="$LIBS -lasound"
- cat >>confdefs.h <<\_ACEOF
-#define PA_USE_ALSA 1
-_ACEOF
-
- fi
-
- if [ $with_oss != "no" ] ; then
- cat >>confdefs.h <<\_ACEOF
-#define PA_USE_OSS 1
-_ACEOF
-
- fi
- LIBS="$LIBS -lm -lpthread";
- PADLL="libportaudio.so";
- PACPP_DLL="libportaudiocpp.so";
- SHARED_FLAGS="-shared";
-esac
-
- ac_config_files="$ac_config_files Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-{
- (set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
- ;;
- esac;
-} |
- sed '
- t clear
- : clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
- if test -w $cache_file; then
- test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
- cat confcache >$cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[ ]*$//;
-}'
-fi
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section. Otherwise,
-# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
-t clear
-: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
-t quote
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
-t quote
-d
-: quote
-s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
-s,\[,\\&,g
-s,\],\\&,g
-s,\$,$$,g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output. A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
-
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_i=`echo "$ac_i" |
- sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
- # 2. Add them.
- ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
- ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
-fi
-
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
- sed '
- N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
- t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
- ' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
- # Exit status is that of the last command.
- exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
- else
- as_ln_s='ln -s'
- fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-exec 6>&1
-
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling. Logging --version etc. is OK.
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
-
-This file was extended by PortAudioCpp $as_me 12, which was
-generated by GNU Autoconf 2.57. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
-_ACEOF
-
-# Files that config.status was made for.
-if test -n "$ac_config_files"; then
- echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_headers"; then
- echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_links"; then
- echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_commands"; then
- echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
- -h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
-
-Configuration files:
-$config_files
-
-Report bugs to <bug-autoconf@gnu.org>."
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-PortAudioCpp config.status 12
-configured by $0, generated by GNU Autoconf 2.57,
- with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
-INSTALL="$INSTALL"
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "x$1" : 'x\([^=]*\)='`
- ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- -*)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- *) # This is not an option, so the user has probably given explicit
- # arguments.
- ac_option=$1
- ac_need_defaults=false;;
- esac
-
- case $ac_option in
- # Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --vers* | -V )
- echo "$ac_cs_version"; exit 0 ;;
- --he | --h)
- # Conflict between --help and --header
- { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; };;
- --help | --hel | -h )
- echo "$ac_cs_usage"; exit 0 ;;
- --debug | --d* | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
- ac_need_defaults=false;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; } ;;
-
- *) ac_config_targets="$ac_config_targets $1" ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
- echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
-
-_ACEOF
-
-
-
-
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_config_target in $ac_config_targets
-do
- case "$ac_config_target" in
- # Handling of arguments.
- "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
- esac
-done
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
-$debug ||
-{
- trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./confstat$$-$RANDOM
- (umask 077 && mkdir $tmp)
-} ||
-{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
-}
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-
-#
-# CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
- # Protect against being on the right side of a sed subst in config.status.
- sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
- s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s,@SHELL@,$SHELL,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s,@exec_prefix@,$exec_prefix,;t t
-s,@prefix@,$prefix,;t t
-s,@program_transform_name@,$program_transform_name,;t t
-s,@bindir@,$bindir,;t t
-s,@sbindir@,$sbindir,;t t
-s,@libexecdir@,$libexecdir,;t t
-s,@datadir@,$datadir,;t t
-s,@sysconfdir@,$sysconfdir,;t t
-s,@sharedstatedir@,$sharedstatedir,;t t
-s,@localstatedir@,$localstatedir,;t t
-s,@libdir@,$libdir,;t t
-s,@includedir@,$includedir,;t t
-s,@oldincludedir@,$oldincludedir,;t t
-s,@infodir@,$infodir,;t t
-s,@mandir@,$mandir,;t t
-s,@build_alias@,$build_alias,;t t
-s,@host_alias@,$host_alias,;t t
-s,@target_alias@,$target_alias,;t t
-s,@DEFS@,$DEFS,;t t
-s,@ECHO_C@,$ECHO_C,;t t
-s,@ECHO_N@,$ECHO_N,;t t
-s,@ECHO_T@,$ECHO_T,;t t
-s,@LIBS@,$LIBS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@CXX@,$CXX,;t t
-s,@CXXFLAGS@,$CXXFLAGS,;t t
-s,@ac_ct_CXX@,$ac_ct_CXX,;t t
-s,@LN_S@,$LN_S,;t t
-s,@RANLIB@,$RANLIB,;t t
-s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
-s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
-s,@INSTALL_DATA@,$INSTALL_DATA,;t t
-s,@AR@,$AR,;t t
-s,@PACPP_ROOT@,$PACPP_ROOT,;t t
-s,@PORTAUDIO@,$PORTAUDIO,;t t
-s,@PADLL@,$PADLL,;t t
-s,@PACPP_DLL@,$PACPP_DLL,;t t
-s,@PACPP_INC@,$PACPP_INC,;t t
-s,@SHARED_FLAGS@,$SHARED_FLAGS,;t t
-s,@DLL_LIBS@,$DLL_LIBS,;t t
-s,@build@,$build,;t t
-s,@build_cpu@,$build_cpu,;t t
-s,@build_vendor@,$build_vendor,;t t
-s,@build_os@,$build_os,;t t
-s,@host@,$host,;t t
-s,@host_cpu@,$host_cpu,;t t
-s,@host_vendor@,$host_vendor,;t t
-s,@host_os@,$host_os,;t t
-s,@PKG_CONFIG@,$PKG_CONFIG,;t t
-s,@JACK_CFLAGS@,$JACK_CFLAGS,;t t
-s,@JACK_LIBS@,$JACK_LIBS,;t t
-s,@LIBOBJS@,$LIBOBJS,;t t
-s,@LTLIBOBJS@,$LTLIBOBJS,;t t
-CEOF
-
-_ACEOF
-
- cat >>$CONFIG_STATUS <<\_ACEOF
- # Split the substitutions into bite-sized pieces for seds with
- # small command number limits, like on Digital OSF/1 and HP-UX.
- ac_max_sed_lines=48
- ac_sed_frag=1 # Number of current file.
- ac_beg=1 # First line for current file.
- ac_end=$ac_max_sed_lines # Line after last line for current file.
- ac_more_lines=:
- ac_sed_cmds=
- while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- else
- sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- fi
- if test ! -s $tmp/subs.frag; then
- ac_more_lines=false
- else
- # The purpose of the label and of the branching condition is to
- # speed up the sed processing (if there are no `@' at all, there
- # is no need to browse any of the substitutions).
- # These are the two extra sed commands mentioned above.
- (echo ':t
- /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
- fi
- ac_sed_frag=`expr $ac_sed_frag + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_lines`
- fi
- done
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
- fi
-fi # test -n "$CONFIG_FILES"
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case $ac_file in
- - | *:- | *:-:* ) # input from stdin
- cat >$tmp/stdin
- ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- * ) ac_file_in=$ac_file.in ;;
- esac
-
- # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
- ac_dir=`(dirname "$ac_file") 2>/dev/null ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- { if $as_mkdir_p; then
- mkdir -p "$ac_dir"
- else
- as_dir="$ac_dir"
- as_dirs=
- while test ! -d "$as_dir"; do
- as_dirs="$as_dir $as_dirs"
- as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- done
- test ! -n "$as_dirs" || mkdir $as_dirs
- fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }; }
-
- ac_builddir=.
-
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
- .) # No --srcdir option. We are building in place.
- ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
-
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
- esac
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- if test x"$ac_file" = x-; then
- configure_input=
- else
- configure_input="$ac_file. "
- fi
- configure_input=$configure_input"Generated from `echo $ac_file_in |
- sed 's,.*/,,'` by configure."
-
- # First look for the input files in the build tree, otherwise in the
- # src tree.
- ac_file_inputs=`IFS=:
- for f in $ac_file_in; do
- case $f in
- -) echo $tmp/stdin ;;
- [\\/$]*)
- # Absolute (can't be DOS-style, as IFS=:)
- test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- echo $f;;
- *) # Relative
- if test -f "$f"; then
- # Build tree
- echo $f
- elif test -f "$srcdir/$f"; then
- # Source tree
- echo $srcdir/$f
- else
- # /dev/null tree
- { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- fi;;
- esac
- done` || { (exit 1); exit 1; }
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s,@configure_input@,$configure_input,;t t
-s,@srcdir@,$ac_srcdir,;t t
-s,@abs_srcdir@,$ac_abs_srcdir,;t t
-s,@top_srcdir@,$ac_top_srcdir,;t t
-s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s,@builddir@,$ac_builddir,;t t
-s,@abs_builddir@,$ac_abs_builddir,;t t
-s,@top_builddir@,$ac_top_builddir,;t t
-s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
-s,@INSTALL@,$ac_INSTALL,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
- rm -f $tmp/stdin
- if test x"$ac_file" != x-; then
- mv $tmp/out $ac_file
- else
- cat $tmp/out
- rm -f $tmp/out
- fi
-
-done
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-{ (exit 0); exit 0; }
-_ACEOF
-chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || { (exit 1); exit 1; }
-fi
-
diff --git a/portaudio/bindings/cpp/build/gnu/configure.ac b/portaudio/bindings/cpp/build/gnu/configure.ac
deleted file mode 100644
index 5457c53..0000000
--- a/portaudio/bindings/cpp/build/gnu/configure.ac
+++ /dev/null
@@ -1,214 +0,0 @@
-#
-# PortAudioCpp V19 autoconf input file
-# Shamelessly ripped from the PortAudio one by Dominic Mazzoni
-# Ludwig Schwardt
-#
-
-# Require autoconf >= 2.13
-AC_PREREQ(2.13)
-
-AC_INIT([PortAudioCpp], [12])
-AC_CONFIG_SRCDIR([../../include/portaudiocpp/PortAudioCpp.hxx])
-
-###### Top-level directory of pacpp
-###### This makes it easy to shuffle the build directories
-###### Also edit AC_CONFIG_SRCDIR above (wouldn't accept this variable)!
-PACPP_ROOT="../.."
-
-######
-###### SET THIS TO PORTAUDIO DIRECTORY
-######
-PORTAUDIO="$PACPP_ROOT/../portaudio"
-
-# Various other variables and flags
-
-PACPP_INC="$PACPP_ROOT/include"
-INCLUDES="-I$PACPP_INC -I$PORTAUDIO -I$PORTAUDIO/pa_common"
-CFLAGS="-g -O2 -Wall -ansi -pedantic $INCLUDES"
-CXXFLAGS="$CFLAGS"
-PALIBDIR="$PORTAUDIO/lib"
-
-# Checks for programs
-
-AC_PROG_CC
-AC_PROG_CXX
-AC_PROG_LN_S
-AC_PROG_RANLIB
-AC_PROG_INSTALL
-AC_PATH_PROG(AR, ar, no)
-if [[ $AR = "no" ]] ; then
- AC_MSG_ERROR("Could not find ar - needed to create a library");
-fi
-
-# This must be one of the first tests we do or it will fail...
-AC_C_BIGENDIAN
-
-# Transfer these variables to the Makefile
-AC_SUBST(PACPP_ROOT)
-AC_SUBST(PORTAUDIO)
-AC_SUBST(PADLL)
-AC_SUBST(PACPP_DLL)
-AC_SUBST(PACPP_INC)
-AC_SUBST(SHARED_FLAGS)
-AC_SUBST(DLL_LIBS)
-AC_SUBST(CXXFLAGS)
-
-##################### CHECK FOR INSTALLED PACKAGES ############################
-
-# checks for various host APIs and arguments to configure that
-# turn them on or off
-
-AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no)
-
-# Determine the host description for the subsequent test.
-# PKG_CHECK_MODULES seems to check and set the host variable also, but
-# that then requires pkg-config availability which is not standard on
-# MinGW systems and can be a pain to install.
-AC_CANONICAL_HOST
-
-PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no)
-
-AC_ARG_WITH(alsa,
- [ --with-alsa (default=auto)],
- with_alsa=$withval, with_alsa="yes")
-
-AC_ARG_WITH(jack,
- [ --with-jack (default=auto)],
- with_jack=$withval, with_jack="yes")
-
-AC_ARG_WITH(oss,
- [ --with-oss (default=yes)],
- with_oss=$withval, with_oss="yes")
-
-AC_ARG_WITH(host_os,
- [ --with-host_os (no default)],
- host_os=$withval)
-
-AC_ARG_WITH(winapi,
- [ --with-winapi ((wmme/directx/asio) default=wmme)],
- with_winapi=$withval, with_winapi="wmme")
-
-# Mac API added for ASIO, can have other api's listed
-AC_ARG_WITH(macapi,
- [ --with-macapi (asio) default=asio)],
- with_macapi=$withval, with_macapi="asio")
-
-AC_ARG_WITH(asiodir,
- [ --with-asiodir (default=/usr/local/asiosdk2)],
- with_asiodir=$withval, with_asiodir="/usr/local/asiosdk2")
-
-AC_ARG_WITH(dxdir,
- [ --with-dxdir (default=/usr/local/dx7sdk)],
- with_dxdir=$withval, with_dxdir="/usr/local/dx7sdk")
-
-
-##################### HOST-SPECIFIC LIBRARY SETTINGS ##########################
-
-case "${host_os}" in
- darwin* )
- # Mac OS X configuration
-
- LIBS="-framework AudioUnit -framework AudioToolbox -framework CoreAudio";
- PADLL="libportaudio.dylib";
- PACPP_DLL="libportaudiocpp.dylib";
- SHARED_FLAGS="-framework AudioUnit -framework AudioToolbox";
- SHARED_FLAGS="$SHARED_FLAGS -framework CoreAudio -dynamiclib";
- if [[ $with_macapi = "asio" ]] ; then
- if [[ $with_asiodir ]] ; then
- ASIODIR="$with_asiodir";
- else
- ASIODIR="/usr/local/asiosdk2";
- fi
- echo "ASIODIR: $ASIODIR";
- fi
- ;;
-
- mingw* )
- # MingW configuration
-
- echo "WINAPI: $with_winapi"
- if [[ $with_winapi = "directx" ]] ; then
- if [[ $with_dxdir ]] ; then
- DXDIR="$with_dxdir";
- else
- DXDIR="/usr/local/dx7sdk";
- fi
- echo "DXDIR: $DXDIR"
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -ldsound -lole32";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm -lm -L./dx7sdk/lib -ldsound -lole32";
- CFLAGS="$CFLAGS -DPA_NO_WMME -DPA_NO_ASIO";
- CXXFLAGS="$CFLAGS"
- elif [[ $with_winapi = "asio" ]] ; then
- if [[ $with_asiodir ]] ; then
- ASIODIR="$with_asiodir";
- else
- ASIODIR="/usr/local/asiosdk2";
- fi
- echo "ASIODIR: $ASIODIR"
-
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -lstdc++ -lole32 -luuid";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
- CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -DPA_NO_WMME -DPA_NO_DS -DWINDOWS";
- CXXFLAGS="$CFLAGS";
- else # WMME default
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm -lstdc++ -lole32 -luuid";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm";
- CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_ASIO";
- CXXFLAGS="$CFLAGS";
- fi
- ;;
-
- cygwin* )
- # Cygwin configuration
-
- LIBS="-L$PALIBDIR -lportaudio"
- LIBS="$LIBS -lwinmm -lm";
- PADLL="portaudio.dll";
- PACPP_DLL="portaudiocpp.dll";
- SHARED_FLAGS="-shared -mthreads";
- DLL_LIBS="-lwinmm";
- ;;
-
- *)
- # Unix OSS configuration
-
- AC_CHECK_LIB(pthread, pthread_create,
- ,
- AC_MSG_ERROR([libpthread not found!]))
-
- LIBS="$LIBS -L$PALIBDIR -lportaudio"
-
- if [[ $have_jack = "yes" ] && [ $with_jack != "no" ]] ; then
- LIBS="$LIBS $JACK_LIBS"
- CFLAGS="$CFLAGS $JACK_CFLAGS"
- AC_DEFINE(PA_USE_JACK)
- fi
-
- if [[ $have_alsa = "yes" ] && [ $with_alsa != "no" ]] ; then
- LIBS="$LIBS -lasound"
- AC_DEFINE(PA_USE_ALSA)
- fi
-
- if [[ $with_oss != "no" ]] ; then
- AC_DEFINE(PA_USE_OSS)
- fi
- LIBS="$LIBS -lm -lpthread";
- PADLL="libportaudio.so";
- PACPP_DLL="libportaudiocpp.so";
- SHARED_FLAGS="-shared";
-esac
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
diff --git a/portaudio/bindings/cpp/build/gnu/install-sh b/portaudio/bindings/cpp/build/gnu/install-sh
deleted file mode 100644
index e9de238..0000000
--- a/portaudio/bindings/cpp/build/gnu/install-sh
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission. M.I.T. makes no representations about the
-# suitability of this software for any purpose. It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- chmodcmd=""
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/portaudio/bindings/cpp/build/vc6/devs_example.dsp b/portaudio/bindings/cpp/build/vc6/devs_example.dsp
deleted file mode 100644
index f2778d3..0000000
--- a/portaudio/bindings/cpp/build/vc6/devs_example.dsp
+++ /dev/null
@@ -1,248 +0,0 @@
-# Microsoft Developer Studio Project File - Name="devs_example" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=devs_example - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "devs_example.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "devs_example.mak" CFG="devs_example - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "devs_example - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "devs_example - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "devs_example - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MTd /W3 /GX /O2 /I "../../include/" /I "../../../../include/" /I "../../../../src/common/" /I "../../../../../asiosdk2/common/" /I "../../../../../asiosdk2/host/" /I "../../../../../asiosdk2/host/pc/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x809 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 portaudiocpp-vc6-r.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/devs_example.exe" /libpath:"../../lib"
-
-!ELSEIF "$(CFG)" == "devs_example - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include/" /I "../../../../include/" /I "../../../../src/common/" /I "../../../../../asiosdk2/common/" /I "../../../../../asiosdk2/host/" /I "../../../../../asiosdk2/host/pc/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x809 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 portaudiocpp-vc6-d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/devs_example.exe" /pdbtype:sept /libpath:"../../lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "devs_example - Win32 Release"
-# Name "devs_example - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\iasiothiscallresolver.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_allocation.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\pa_asio.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_converters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_cpuload.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_dither.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_front.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_process.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_stream.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_trace.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_win_hostapis.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_win_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\wmme\pa_win_wmme.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_x86_plain_converters.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\iasiothiscallresolver.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_allocation.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_converters.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_cpuload.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_dither.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_endianness.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_hostapi.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_process.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_stream.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_trace.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_util.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_x86_plain_converters.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Group "Example Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\example\devs.cxx
-# End Source File
-# End Group
-# Begin Group "ASIO 2 SDK"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\common\asio.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\host\asiodrivers.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\host\pc\asiolist.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portaudio/bindings/cpp/build/vc6/devs_example.dsw b/portaudio/bindings/cpp/build/vc6/devs_example.dsw
deleted file mode 100644
index 6c3bc6d..0000000
--- a/portaudio/bindings/cpp/build/vc6/devs_example.dsw
+++ /dev/null
@@ -1,44 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "devs_example"=".\devs_example.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name static_library
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "static_library"=".\static_library.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portaudio/bindings/cpp/build/vc6/sine_example.dsp b/portaudio/bindings/cpp/build/vc6/sine_example.dsp
deleted file mode 100644
index 2c4dbeb..0000000
--- a/portaudio/bindings/cpp/build/vc6/sine_example.dsp
+++ /dev/null
@@ -1,252 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sine_example" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=sine_example - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "sine_example.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "sine_example.mak" CFG="sine_example - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "sine_example - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "sine_example - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "sine_example - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MTd /W3 /GX /O2 /I "../../include/" /I "../../../../include/" /I "../../../../src/common/" /I "../../../../../asiosdk2/common/" /I "../../../../../asiosdk2/host/" /I "../../../../../asiosdk2/host/pc/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x809 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 portaudiocpp-vc6-r.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/sine_example.exe" /libpath:"../../lib"
-
-!ELSEIF "$(CFG)" == "sine_example - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include/" /I "../../../../include/" /I "../../../../src/common/" /I "../../../../../asiosdk2/common/" /I "../../../../../asiosdk2/host/" /I "../../../../../asiosdk2/host/pc/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x809 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 portaudiocpp-vc6-d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/sine_example.exe" /pdbtype:sept /libpath:"../../lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "sine_example - Win32 Release"
-# Name "sine_example - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\iasiothiscallresolver.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_allocation.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_converters.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_cpuload.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_dither.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_endianness.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_hostapi.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_process.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_stream.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_trace.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_util.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_x86_plain_converters.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Group "Example Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\example\sine.cxx
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\iasiothiscallresolver.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_allocation.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\pa_asio\pa_asio.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_converters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_cpuload.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_dither.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_front.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_process.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_stream.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\common\pa_trace.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_win_hostapis.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_win_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\wasapi\pa_win_wasapi.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\hostapi\wmme\pa_win_wmme.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\src\os\win\pa_x86_plain_converters.c
-# End Source File
-# End Group
-# Begin Group "ASIO 2 SDK"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\common\asio.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\host\asiodrivers.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\..\asiosdk2\host\pc\asiolist.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portaudio/bindings/cpp/build/vc6/sine_example.dsw b/portaudio/bindings/cpp/build/vc6/sine_example.dsw
deleted file mode 100644
index d3c2b62..0000000
--- a/portaudio/bindings/cpp/build/vc6/sine_example.dsw
+++ /dev/null
@@ -1,44 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "sine_example"=".\sine_example.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name static_library
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "static_library"=".\static_library.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portaudio/bindings/cpp/build/vc6/static_library.dsp b/portaudio/bindings/cpp/build/vc6/static_library.dsp
deleted file mode 100644
index 4e9ded3..0000000
--- a/portaudio/bindings/cpp/build/vc6/static_library.dsp
+++ /dev/null
@@ -1,395 +0,0 @@
-# Microsoft Developer Studio Project File - Name="static_library" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=static_library - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "static_library.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "static_library.mak" CFG="static_library - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "static_library - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "static_library - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MTd /W3 /GX /O2 /I "../../include/" /I "../../../../include/" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x809 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../../lib/portaudiocpp-vc6-r.lib"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include/" /I "../../../../include/" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x809 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../../lib/portaudiocpp-vc6-d.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "static_library - Win32 Release"
-# Name "static_library - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\AsioDeviceAdapter.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\BlockingStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\CallbackInterface.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\CallbackStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\CFunCallbackStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\CppFunCallbackStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\Device.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\DirectionSpecificStreamParameters.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\Exception.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\HostApi.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\InterfaceCallbackStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\MemFunCallbackStream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\Stream.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\StreamParameters.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\System.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\SystemDeviceIterator.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\source\portaudiocpp\SystemHostApiIterator.cxx
-
-!IF "$(CFG)" == "static_library - Win32 Release"
-
-!ELSEIF "$(CFG)" == "static_library - Win32 Debug"
-
-# SUBTRACT CPP /YX
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\AsioDeviceAdapter.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\AutoSystem.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\BlockingStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\CallbackInterface.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\CallbackStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\CFunCallbackStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\CppFunCallbackStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\Device.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\DirectionSpecificStreamParameters.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\Exception.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\HostApi.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\InterfaceCallbackStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\MemFunCallbackStream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\PortAudioCpp.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\SampleDataFormat.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\Stream.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\StreamParameters.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\System.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\SystemDeviceIterator.hxx
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\portaudiocpp\SystemHostApiIterator.hxx
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portaudio/bindings/cpp/build/vc6/static_library.dsw b/portaudio/bindings/cpp/build/vc6/static_library.dsw
deleted file mode 100644
index 0aff3f5..0000000
--- a/portaudio/bindings/cpp/build/vc6/static_library.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "static_library"=".\static_library.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portaudio/bindings/cpp/build/vc7/OUT_OF_DATE b/portaudio/bindings/cpp/build/vc7/OUT_OF_DATE
deleted file mode 100644
index e69de29..0000000
--- a/portaudio/bindings/cpp/build/vc7/OUT_OF_DATE
+++ /dev/null
diff --git a/portaudio/bindings/cpp/build/vc7_1/devs_example.sln b/portaudio/bindings/cpp/build/vc7_1/devs_example.sln
deleted file mode 100644
index ef11811..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/devs_example.sln
+++ /dev/null
@@ -1,30 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "devs_example", "devs_example.vcproj", "{1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}"
- ProjectSection(ProjectDependencies) = postProject
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A} = {D18EA0C9-8C65-441D-884C-55EB43A84F2A}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_library", "static_library.vcproj", "{D18EA0C9-8C65-441D-884C-55EB43A84F2A}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Debug.ActiveCfg = Debug|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Debug.Build.0 = Debug|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Release.ActiveCfg = Release|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Release.Build.0 = Release|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.ActiveCfg = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.Build.0 = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.ActiveCfg = Release|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/portaudio/bindings/cpp/build/vc7_1/devs_example.vcproj b/portaudio/bindings/cpp/build/vc7_1/devs_example.vcproj
deleted file mode 100644
index b4095e4..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/devs_example.vcproj
+++ /dev/null
@@ -1,195 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="devs_example"
- ProjectGUID="{1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../include/;../../../../include/;../../../../src/common/;../../../../../asiosdk2/common/,../../../../../asiosdk2/host/,../../../../../asiosdk2/host/pc/"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="../../lib/portaudiocpp-vc7_1-d.lib"
- OutputFile="../../bin/devs_example.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/devs_example.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include/;../../../../include/;../../../../src/common/;../../../../../asiosdk2/common/,../../../../../asiosdk2/host/,../../../../../asiosdk2/host/pc/"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="../../lib/portaudiocpp-vc7_1-r.lib"
- OutputFile="../../bin/devs_example.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Files"
- Filter="">
- <File
- RelativePath="..\..\example\devs.cxx">
- </File>
- </Filter>
- <Filter
- Name="PortAudio v19 Files"
- Filter="">
- <File
- RelativePath="..\..\..\..\src\common\pa_allocation.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\asio\pa_asio.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_converters.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_cpuload.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_dither.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_front.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_process.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_stream.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_trace.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\dsound\pa_win_ds.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_win_hostapis.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_win_util.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\wasapi\pa_win_wasapi.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\wmme\pa_win_wmme.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_x86_plain_converters.c">
- </File>
- </Filter>
- <Filter
- Name="ASIO 2 SDK Files"
- Filter="">
- <File
- RelativePath="..\..\..\..\..\asiosdk2\common\asio.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\..\asiosdk2\host\asiodrivers.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\..\asiosdk2\host\pc\asiolist.cpp">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/portaudio/bindings/cpp/build/vc7_1/sine_example.sln b/portaudio/bindings/cpp/build/vc7_1/sine_example.sln
deleted file mode 100644
index b3c9b29..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/sine_example.sln
+++ /dev/null
@@ -1,30 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sine_example", "sine_example.vcproj", "{1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}"
- ProjectSection(ProjectDependencies) = postProject
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A} = {D18EA0C9-8C65-441D-884C-55EB43A84F2A}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_library", "static_library.vcproj", "{D18EA0C9-8C65-441D-884C-55EB43A84F2A}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Debug.ActiveCfg = Debug|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Debug.Build.0 = Debug|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Release.ActiveCfg = Release|Win32
- {1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}.Release.Build.0 = Release|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.ActiveCfg = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.Build.0 = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.ActiveCfg = Release|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/portaudio/bindings/cpp/build/vc7_1/sine_example.vcproj b/portaudio/bindings/cpp/build/vc7_1/sine_example.vcproj
deleted file mode 100644
index 656393d..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/sine_example.vcproj
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="sine_example"
- ProjectGUID="{1B9A038D-80A3-4DBD-9F0D-AF10B49B863A}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../include/;../../../../include/;../../../../src/common/;../../../../../asiosdk2/common/,../../../../../asiosdk2/host/,../../../../../asiosdk2/host/pc/"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="../../lib/portaudiocpp-vc7_1-d.lib"
- OutputFile="../../bin/sine_example.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/sine_example.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include/;../../../../include/;../../../../src/common/;../../../../../asiosdk2/common/,../../../../../asiosdk2/host/,../../../../../asiosdk2/host/pc/"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="../../lib/portaudiocpp-vc7_1-r.lib"
- OutputFile="../../bin/sine_example.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Files"
- Filter="">
- <File
- RelativePath="..\..\example\sine.cxx">
- </File>
- </Filter>
- <Filter
- Name="PortAudio v19 Files"
- Filter="">
- <File
- RelativePath="..\..\..\..\src\common\pa_allocation.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\asio\pa_asio.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_converters.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_cpuload.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_dither.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_front.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_process.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_stream.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\common\pa_trace.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\dsound\pa_win_ds.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\dsound\pa_win_ds_dynlink.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_win_hostapis.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_win_util.c">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\wasapi\pa_win_wasapi.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\src\hostapi\wmme\pa_win_wmme.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)/$(InputName)1.obj"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\..\src\os\win\pa_x86_plain_converters.c">
- </File>
- </Filter>
- <Filter
- Name="ASIO 2 SDK Files"
- Filter="">
- <File
- RelativePath="..\..\..\..\..\asiosdk2\common\asio.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\..\asiosdk2\host\asiodrivers.cpp">
- </File>
- <File
- RelativePath="..\..\..\..\..\asiosdk2\host\pc\asiolist.cpp">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/portaudio/bindings/cpp/build/vc7_1/static_library.sln b/portaudio/bindings/cpp/build/vc7_1/static_library.sln
deleted file mode 100644
index 4ec0b6b..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/static_library.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_library", "static_library.vcproj", "{D18EA0C9-8C65-441D-884C-55EB43A84F2A}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.ActiveCfg = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Debug.Build.0 = Debug|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.ActiveCfg = Release|Win32
- {D18EA0C9-8C65-441D-884C-55EB43A84F2A}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/portaudio/bindings/cpp/build/vc7_1/static_library.vcproj b/portaudio/bindings/cpp/build/vc7_1/static_library.vcproj
deleted file mode 100644
index 1b060ce..0000000
--- a/portaudio/bindings/cpp/build/vc7_1/static_library.vcproj
+++ /dev/null
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="static_library"
- ProjectGUID="{D18EA0C9-8C65-441D-884C-55EB43A84F2A}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../lib/"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../include/;../../../../include/"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/portaudiocpp-vc7_1-d.lib"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../lib/"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include/;../../../../include/"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(IntDir)/vc71.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/portaudiocpp-vc7_1-r.lib"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Files"
- Filter="">
- <File
- RelativePath="..\..\source\portaudiocpp\AsioDeviceAdapter.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\AsioDeviceAdapter.hxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\AutoSystem.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\BlockingStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\BlockingStream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\CallbackInterface.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\CallbackInterface.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\CallbackStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\CallbackStream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\CFunCallbackStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\CFunCallbackStream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\CppFunCallbackStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\CppFunCallbackStream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\Device.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\Device.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\DirectionSpecificStreamParameters.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\DirectionSpecificStreamParameters.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\Exception.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\Exception.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\HostApi.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\HostApi.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\InterfaceCallbackStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\InterfaceCallbackStream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\MemFunCallbackStream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\MemFunCallbackStream.hxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\PortAudioCpp.hxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\SampleDataFormat.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\Stream.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\Stream.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\StreamParameters.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\StreamParameters.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\System.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\System.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\SystemDeviceIterator.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\SystemDeviceIterator.hxx">
- </File>
- <File
- RelativePath="..\..\source\portaudiocpp\SystemHostApiIterator.cxx">
- </File>
- <File
- RelativePath="..\..\include\portaudiocpp\SystemHostApiIterator.hxx">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.sln b/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.sln
deleted file mode 100644
index 6f8ef5f..0000000
--- a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.sln
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PortAudioJNI", "PortAudioJNI.vcxproj", "{4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Debug|Win32.ActiveCfg = Debug|Win32
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Debug|Win32.Build.0 = Debug|Win32
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Debug|x64.ActiveCfg = Debug|x64
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Debug|x64.Build.0 = Debug|x64
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Release|Win32.ActiveCfg = Release|Win32
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Release|Win32.Build.0 = Release|Win32
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Release|x64.ActiveCfg = Release|x64
- {4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcproj b/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcproj
deleted file mode 100644
index ce83264..0000000
--- a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcproj
+++ /dev/null
@@ -1,198 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9.00"
- Name="PortAudioJNI"
- ProjectGUID="{4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}"
- RootNamespace="PortAudioJNI"
- Keyword="Win32Proj"
- TargetFrameworkVersion="196613"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\..\..\..\jportaudio"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="C:\glassfish3\jdk\include;C:\glassfish3\jdk\include\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- EnableIntrinsicFunctions="true"
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="2"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\com_portaudio_PortAudio.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\..\src\com_portaudio_PortAudio.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcxproj b/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcxproj
deleted file mode 100644
index c7e881b..0000000
--- a/portaudio/bindings/java/c/build/vs2010/PortAudioJNI/PortAudioJNI.vcxproj
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{4024D885-39B0-4C8A-B3E7-BAB4BA08DFBB}</ProjectGuid>
- <RootNamespace>PortAudioJNI</RootNamespace>
- <Keyword>Win32Proj</Keyword>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\jportaudio\</OutDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\..\jportaudio\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\jportaudio\</OutDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\..\jportaudio\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">jportaudio_x64</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">jportaudio_x86</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">jportaudio_x86</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">jportaudio_x64</TargetName>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\..\..\..\..\include;%JAVA_HOME%\include;%JAVA_HOME%\include\win32</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\..\..\..\..\include;%JAVA_HOME%\include;%JAVA_HOME%\include\win32</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\..\..\..\..\..\include;%JAVA_HOME%\include;%JAVA_HOME%\include\win32</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <TargetMachine>MachineX86</TargetMachine>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PORTAUDIOJNI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\..\..\..\..\..\include;%JAVA_HOME%\include;%JAVA_HOME%\include\win32</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\..\src\com_portaudio_BlockingStream.c" />
- <ClCompile Include="..\..\..\src\com_portaudio_PortAudio.c" />
- <ClCompile Include="..\..\..\src\jpa_tools.c" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\src\com_portaudio_BlockingStream.h" />
- <ClInclude Include="..\..\..\src\com_portaudio_PortAudio.h" />
- <ClInclude Include="..\..\..\src\jpa_tools.h" />
- </ItemGroup>
- <ItemGroup>
- <Library Include="..\..\..\..\jportaudio\portaudio_x64.lib" />
- <Library Include="..\..\..\..\jportaudio\portaudio_x86.lib" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/portaudio/build/msvc/portaudio.def b/portaudio/build/msvc/portaudio.def
deleted file mode 100644
index 6ecb142..0000000
--- a/portaudio/build/msvc/portaudio.def
+++ /dev/null
@@ -1,58 +0,0 @@
-EXPORTS
-
-;
-Pa_GetVersion @1
-Pa_GetVersionText @2
-Pa_GetErrorText @3
-Pa_Initialize @4
-Pa_Terminate @5
-Pa_GetHostApiCount @6
-Pa_GetDefaultHostApi @7
-Pa_GetHostApiInfo @8
-Pa_HostApiTypeIdToHostApiIndex @9
-Pa_HostApiDeviceIndexToDeviceIndex @10
-Pa_GetLastHostErrorInfo @11
-Pa_GetDeviceCount @12
-Pa_GetDefaultInputDevice @13
-Pa_GetDefaultOutputDevice @14
-Pa_GetDeviceInfo @15
-Pa_IsFormatSupported @16
-Pa_OpenStream @17
-Pa_OpenDefaultStream @18
-Pa_CloseStream @19
-Pa_SetStreamFinishedCallback @20
-Pa_StartStream @21
-Pa_StopStream @22
-Pa_AbortStream @23
-Pa_IsStreamStopped @24
-Pa_IsStreamActive @25
-Pa_GetStreamInfo @26
-Pa_GetStreamTime @27
-Pa_GetStreamCpuLoad @28
-Pa_ReadStream @29
-Pa_WriteStream @30
-Pa_GetStreamReadAvailable @31
-Pa_GetStreamWriteAvailable @32
-Pa_GetSampleSize @33
-Pa_Sleep @34
-PaAsio_GetAvailableBufferSizes @50
-PaAsio_ShowControlPanel @51
-PaUtil_InitializeX86PlainConverters @52
-PaAsio_GetInputChannelName @53
-PaAsio_GetOutputChannelName @54
-PaUtil_SetDebugPrintFunction @55
-PaWasapi_GetAudioClient @56
-PaWasapi_UpdateDeviceList @57
-PaWasapi_GetDeviceCurrentFormat @58
-PaWasapi_GetDeviceDefaultFormat @59
-PaWasapi_GetDeviceMixFormat @60
-PaWasapi_GetDeviceRole @61
-PaWasapi_ThreadPriorityBoost @62
-PaWasapi_ThreadPriorityRevert @63
-PaWasapi_GetFramesPerHostBuffer @64
-PaWasapi_GetJackCount @65
-PaWasapi_GetJackDescription @66
-PaWasapi_SetStreamStateHandler @68
-PaWasapiWinrt_SetDefaultDeviceId @67
-PaWasapiWinrt_PopulateDeviceList @69
-PaWasapi_GetIMMDevice @70
diff --git a/portaudio/build/msvc/portaudio.dsp b/portaudio/build/msvc/portaudio.dsp
deleted file mode 100644
index 44fdd30..0000000
--- a/portaudio/build/msvc/portaudio.dsp
+++ /dev/null
@@ -1,269 +0,0 @@
-# Microsoft Developer Studio Project File - Name="portaudio" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=portaudio - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "portaudio.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "portaudio.mak" CFG="portaudio - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "portaudio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "portaudio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "portaudio - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release_x86"
-# PROP BASE Intermediate_Dir "Release_x86"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release_x86"
-# PROP Intermediate_Dir "Release_x86"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\src\common" /I "..\..\include" /I ".\\" /I "..\..\src\os\win" /D "WIN32" /D "NDEBUG" /D "_USRDLL" /D "PA_ENABLE_DEBUG_OUTPUT" /D "_CRT_SECURE_NO_DEPRECATE" /D "PAWIN_USE_WDMKS_DEVICE_INFO" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /dll /machine:I386 /out:"./Release_x86/portaudio_x86.dll"
-
-!ELSEIF "$(CFG)" == "portaudio - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug_x86"
-# PROP BASE Intermediate_Dir "Debug_x86"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug_x86"
-# PROP Intermediate_Dir "Debug_x86"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\src\common" /I "..\..\include" /I ".\\" /I "..\..\src\os\win" /D "WIN32" /D "_DEBUG" /D "_USRDLL" /D "PA_ENABLE_DEBUG_OUTPUT" /D "_CRT_SECURE_NO_DEPRECATE" /D "PAWIN_USE_WDMKS_DEVICE_INFO" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /dll /debug /machine:I386 /out:"./Debug_x86/portaudio_x86.dll" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "portaudio - Win32 Release"
-# Name "portaudio - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "common"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_allocation.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_converters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_cpuload.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_debugprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_dither.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_front.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_process.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_ringbuffer.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\common\pa_stream.c
-# End Source File
-# End Group
-# Begin Group "hostapi"
-
-# PROP Default_Filter ""
-# Begin Group "ASIO"
-
-# PROP Default_Filter ""
-# Begin Group "ASIOSDK"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\common\asio.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\host\ASIOConvertSamples.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\host\asiodrivers.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\host\pc\asiolist.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\common\combase.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\common\debugmessage.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\ASIOSDK\common\register.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\asio\pa_asio.cpp
-# ADD CPP /I "..\..\src\hostapi\asio\ASIOSDK\host" /I "..\..\src\hostapi\asio\ASIOSDK\host\pc" /I "..\..\src\hostapi\asio\ASIOSDK\common"
-# End Source File
-# End Group
-# Begin Group "dsound"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\dsound\pa_win_ds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\dsound\pa_win_ds_dynlink.c
-# End Source File
-# End Group
-# Begin Group "wmme"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\wmme\pa_win_wmme.c
-# End Source File
-# End Group
-# Begin Group "wasapi"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\wasapi\pa_win_wasapi.cpp
-# End Source File
-# End Group
-# Begin Group "wdm-ks"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\hostapi\wdmks\pa_win_wdmks.c
-# End Source File
-# End Group
-# End Group
-# Begin Group "os"
-
-# PROP Default_Filter ""
-# Begin Group "win"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\src\os\win\pa_win_hostapis.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\os\win\pa_win_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\os\win\pa_win_waveformat.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\os\win\pa_win_wdmks_utils.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\os\win\pa_x86_plain_converters.c
-# End Source File
-# End Group
-# End Group
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=.\portaudio.def
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/portaudio/build/msvc/portaudio.dsw b/portaudio/build/msvc/portaudio.dsw
deleted file mode 100644
index 58d0ea9..0000000
--- a/portaudio/build/msvc/portaudio.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "portaudio"=".\portaudio.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/portaudio/build/msvc/portaudio.sln b/portaudio/build/msvc/portaudio.sln
deleted file mode 100644
index ef9456e..0000000
--- a/portaudio/build/msvc/portaudio.sln
+++ /dev/null
@@ -1,32 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portaudio", "portaudio.vcproj", "{0A18A071-125E-442F-AFF7-A3F68ABECF99}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- ReleaseMinDependency|Win32 = ReleaseMinDependency|Win32
- ReleaseMinDependency|x64 = ReleaseMinDependency|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.ReleaseMinDependency|Win32.ActiveCfg = ReleaseMinDependency|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.ReleaseMinDependency|Win32.Build.0 = ReleaseMinDependency|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.ReleaseMinDependency|x64.ActiveCfg = ReleaseMinDependency|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.ReleaseMinDependency|x64.Build.0 = ReleaseMinDependency|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/portaudio/build/msvc/portaudio.vcproj b/portaudio/build/msvc/portaudio.vcproj
deleted file mode 100644
index e5a648b..0000000
--- a/portaudio/build/msvc/portaudio.vcproj
+++ /dev/null
@@ -1,1932 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="portaudio"
- ProjectGUID="{0A18A071-125E-442F-AFF7-A3F68ABECF99}"
- RootNamespace="portaudio"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Release_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- EnableIntrinsicFunctions="true"
- FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="..\..\src\common;..\..\include;.\;..\..\src\os\win"
- PreprocessorDefinitions="WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)/portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ksuser.lib"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile=".\portaudio.def"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)\portaudio_x86.lib"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Release_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- EnableIntrinsicFunctions="true"
- FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="..\..\src\common;..\..\include;.\;..\..\src\os\win"
- PreprocessorDefinitions="_WIN64;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)\portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ksuser.lib"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x64.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile=".\portaudio.def"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)/portaudio_x64.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)/portaudio_x64.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x64.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\src\common;..\..\include;.\;..\..\src\os\win"
- PreprocessorDefinitions="WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)/portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies=""
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.dll"
- LinkIncremental="2"
- SuppressStartupBanner="true"
- ModuleDefinitionFile=".\portaudio.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)\portaudio_x86.lib"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Debug_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\src\common,..\..\include,.\,..\..\src\os\win"
- PreprocessorDefinitions="_WIN64;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)\portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies=""
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x64.dll"
- LinkIncremental="2"
- SuppressStartupBanner="true"
- ModuleDefinitionFile=".\portaudio.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)/portaudio_x64.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)\portaudio_x64.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)/portaudio_x64.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseMinDependency|Win32"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Release_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- EnableIntrinsicFunctions="true"
- FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="..\..\src\common;..\..\include;.\;..\..\src\os\win"
- PreprocessorDefinitions="WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- StringPooling="true"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)/portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ksuser.lib"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile=".\portaudio.def"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\portaudio_x86.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)\portaudio_x86.lib"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseMinDependency|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Release_x86/portaudio.tlb"
- HeaderFileName=""
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- EnableIntrinsicFunctions="true"
- FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="..\..\src\common;..\..\include;.\;..\..\src\os\win"
- PreprocessorDefinitions="_WIN64;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;PA_USE_ASIO=0;PA_USE_DS=0;PA_USE_WMME=1;PA_USE_WASAPI=1;PA_USE_WDMKS=1"
- StringPooling="true"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(PlatformName)\$(ConfigurationName)\portaudio.pch"
- AssemblerListingLocation="$(PlatformName)\$(ConfigurationName)\"
- ObjectFile="$(PlatformName)\$(ConfigurationName)\"
- ProgramDataBaseFileName="$(PlatformName)\$(ConfigurationName)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ksuser.lib"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x64.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile=".\portaudio.def"
- ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)/portaudio_x64.pdb"
- ImportLibrary="$(PlatformName)\$(ConfigurationName)/portaudio_x64.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- SuppressStartupBanner="true"
- OutputFile="$(PlatformName)\$(ConfigurationName)\portaudio_x64.bsc"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <Filter
- Name="common"
- >
- <File
- RelativePath="..\..\src\common\pa_allocation.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_converters.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_cpuload.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_debugprint.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_dither.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_front.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\hostapi\skeleton\pa_hostapi_skeleton.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_process.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_ringbuffer.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_stream.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\common\pa_trace.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="hostapi"
- >
- <Filter
- Name="ASIO"
- >
- <File
- RelativePath="..\..\src\hostapi\asio\pa_asio.cpp"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <Filter
- Name="ASIOSDK"
- >
- <File
- RelativePath="..\..\src\hostapi\asio\ASIOSDK\common\asio.cpp"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\hostapi\asio\ASIOSDK\host\asiodrivers.cpp"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\hostapi\asio\ASIOSDK\host\pc\asiolist.cpp"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common"
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="dsound"
- >
- <File
- RelativePath="..\..\src\hostapi\dsound\pa_win_ds.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="wmme"
- >
- <File
- RelativePath="..\..\src\hostapi\wmme\pa_win_wmme.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="wasapi"
- >
- <File
- RelativePath="..\..\src\hostapi\wasapi\pa_win_wasapi.c"
- >
- </File>
- </Filter>
- <Filter
- Name="wdmks"
- >
- <File
- RelativePath="..\..\src\hostapi\wdmks\pa_win_wdmks.c"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="os"
- >
- <Filter
- Name="win"
- >
- <File
- RelativePath="..\..\src\os\win\pa_win_coinitialize.c"
- >
- </File>
- <File
- RelativePath="..\..\src\os\win\pa_win_hostapis.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\os\win\pa_win_util.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\src\os\win\pa_win_waveformat.c"
- >
- </File>
- <File
- RelativePath="..\..\src\os\win\pa_win_wdmks_utils.c"
- >
- </File>
- <File
- RelativePath="..\..\src\os\win\pa_x86_plain_converters.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseMinDependency|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- </Filter>
- </Filter>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
- >
- <File
- RelativePath="portaudio.def"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl"
- >
- <File
- RelativePath="..\..\include\pa_asio.h"
- >
- </File>
- <File
- RelativePath="..\..\include\pa_win_ds.h"
- >
- </File>
- <File
- RelativePath="..\..\include\pa_win_wasapi.h"
- >
- </File>
- <File
- RelativePath="..\..\include\pa_win_waveformat.h"
- >
- </File>
- <File
- RelativePath="..\..\include\pa_win_wmme.h"
- >
- </File>
- <File
- RelativePath="..\..\include\portaudio.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/portaudio/build/msvc/readme.txt b/portaudio/build/msvc/readme.txt
deleted file mode 100644
index 07421ff..0000000
--- a/portaudio/build/msvc/readme.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-Hello
-
- This is a small list of steps in order to build portaudio
-(Currently v19-devel) into a VS2005 DLL and lib file.
-This DLL contains all 5 current Win32 PA APIS (MME/DS/ASIO/WASAPI/WDMKS)
-
-1)Copy the source dirs that comes with the ASIO SDK inside src\hostapi\asio\ASIOSDK
- so you should now have example:
-
- portaudio19svn\src\hostapi\asio\ASIOSDK\common
- portaudio19svn\src\hostapi\asio\ASIOSDK\host
- portaudio19svn\src\hostapi\asio\ASIOSDK\host\sample
- portaudio19svn\src\hostapi\asio\ASIOSDK\host\pc
- portaudio19svn\src\hostapi\asio\ASIOSDK\host\mac (not needed)
-
- You dont need "driver"
-
- To build without ASIO (or another Host API) see the "Building without ASIO support" section below.
-
-2)
- *If you have Visual Studio 6.0*, please make sure you have it updated with the latest (and final)
- microsoft libraries for it, namely:
-
- Service pack 5:
- Latest known URL:
- http://msdn2.microsoft.com/en-us/vstudio/aa718363.aspx
- Yes there EXISTS a service pack 6 , but the processor pack (below) isn't compatible with it.
-
- Processor Pack(only works with above SP5)
- Latest known URL:
- http://msdn2.microsoft.com/en-us/vstudio/Aa718349.aspx
- This isn't absolutely required for portaudio, but if you plan on using SSE intrinsics and similar things.
- Up to you to decide upon Service pack 5 or 6 depending on your need for intrinsics.
-
- Platform SDK (Feb 2003) :
- Latest known URL:
- http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
- (This will allow your code base to be x64 friendly, with correct defines
- for LONG_PTR and such)
- NOTE A) Yes you have to use IE activex scripts to install that - wont work in Firefox, you
- may have to temporarily change tyour default browser(aint life unfair)
- NOTE B) Dont forget to hit "Register PSDK Directories with Visual Studio".
- you can make sure its right in VC6 if you open tools/options/directories/include files and you see SDK 2003 as the FIRST entry
- (it must be the same for libs)
-
- DirectX 9.0 SDK Update - (Summer 2003)
- Latest known URL:
- http://www.microsoft.com/downloads/details.aspx?familyid=9216652f-51e0-402e-b7b5-feb68d00f298&displaylang=en
- Again register the links in VC6, and check inside vc6 if headers are in second place right after SDk 2003
-
- *If you have 7.0(VC.NET/2001) or 7.1(VC.2003) *
- then I suggest you open portaudio.dsp (and convert if needed)
-
- *If you have Visual Studio 2005 * (or later), I suggest you open the portaudio.sln file
- which contains 2 projects (portaudio & portaudio_static) each with 6 configurations: Win32/x64 in both Debug, Release and ReleaseMinDependency,
- last of which removes dependency of all but basic OS system DLLs.
-
- hit compile and hope for the best.
-
-3)Now in any project, in which you require portaudio,
- you can just link with portaudio_x86.lib, (or _x64) and of course include the
- relevant headers
- (portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) See (*)
-
-4) Your new exe should now use portaudio_xXX.dll.
-
-
-Have fun!
-
-(*): you may want to add/remove some DLL entry points.
-Right now those 6 entries are _not_ from portaudio.h
-
-(from portaudio.def)
-(...)
-PaAsio_GetAvailableLatencyValues @50
-PaAsio_ShowControlPanel @51
-PaUtil_InitializeX86PlainConverters @52
-PaAsio_GetInputChannelName @53
-PaAsio_GetOutputChannelName @54
-PaUtil_SetLogPrintFunction @55
-
-
-*** Building without ASIO support ***
-
-To build PortAudio without ASIO support you need to:
- A. Make sure your project doesn't try to build any ASIO SDK files.
- If you're using one of the shipped projects, remove the ASIO related files
- from the project.
-
- B. Make sure your project doesn't try to build the PortAudio ASIO
- implementation files:
- src/hostapi/pa_asio.cpp
- src/hostapi/iasiothiscallresolver.cpp
- If you're using one of the shipped projects remove them from the project.
-
- C. Set the PA_USE_ASIO preprocessor symbol to zero (i.e. PA_USE_ASIO=0) in the project properties.
- In VS2005 this can be added under
- Project Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions
-
- Setting PA_USE_ASIO=0 stops src/os/win/pa_win_hostapis.c
- from trying to initialize the PA ASIO implementation.
-
- D. Remove PaAsio_* entry points from portaudio.def, or comment them out with ;
-
-
-A similar procedure can be used to omit any of the other host APIs from the
-build. The relevant preprocessor symbols used by pa_win_hostapis.c are:
-PA_USE_WMME, PA_USE_DSOUND, PA_USE_ASIO, PA_USE_WASAPI and PA_USE_WDMKS
-
------
-David Viens, davidv@plogue.com
-Robert Bielik, robert@xponaut.se
diff --git a/portaudio/build/scons/SConscript_common b/portaudio/build/scons/SConscript_common
deleted file mode 100644
index eaf4e3c..0000000
--- a/portaudio/build/scons/SConscript_common
+++ /dev/null
@@ -1,30 +0,0 @@
-import os.path, sys
-
-class ConfigurationError(Exception):
- def __init__(self, reason):
- Exception.__init__(self, "Configuration failed: %s" % reason)
-
-env = Environment()
-
-# sunos, aix, hpux, irix, sunos appear to be platforms known by SCons, assuming they're POSIX compliant
-Posix = ("linux", "darwin", "sunos", "aix", "hpux", "irix", "sunos", "netbsd")
-Windows = ("win32", "cygwin")
-
-if env["PLATFORM"] == "posix":
- if sys.platform[:5] == "linux":
- Platform = "linux"
- elif sys.platform[:6] == "netbsd":
- Platform = "netbsd"
- else:
- raise ConfigurationError("Unknown platform %s" % sys.platform)
-else:
- if not env["PLATFORM"] in ("win32", "cygwin") + Posix:
- raise ConfigurationError("Unknown platform %s" % env["PLATFORM"])
- Platform = env["PLATFORM"]
-
-# Inspired by the versioning scheme followed by Qt, it seems sensible enough. There are three components: major, minor
-# and micro. Major changes with each subtraction from the API (backward-incompatible, i.e. V19 vs. V18), minor changes
-# with each addition to the API (backward-compatible), micro changes with each revision of the source code.
-ApiVer = "2.0.0"
-
-Export("Platform", "Posix", "ConfigurationError", "ApiVer")
diff --git a/portaudio/build/scons/SConscript_opts b/portaudio/build/scons/SConscript_opts
deleted file mode 100644
index 6a4b0a9..0000000
--- a/portaudio/build/scons/SConscript_opts
+++ /dev/null
@@ -1,91 +0,0 @@
-import os.path, sys
-
-def _PackageOption(pkgName, default=1):
- """ Allow user to choose whether a package should be used if available. This results in a commandline option use<Pkgname>,
- where Pkgname is the name of the package with a capitalized first letter.
- @param pkgName: Name of package.
- @param default: The default value for this option ("yes"/"no").
- """
- return BoolOption("use%s" % pkgName[0].upper() + pkgName[1:], "use %s if available" % (pkgName), default)
-
-def _BoolOption(opt, explanation, default=1):
- """ Allow user to enable/disable a certain option. This results in a commandline option enable<Option>, where Option
- is the name of the option with a capitalized first letter.
- @param opt: Name of option.
- @param explanation: Explanation of option.
- @param default: The default value for this option (1/0).
- """
- return BoolOption("enable%s" % opt[0].upper() + opt[1:], explanation, default)
-
-def _EnumOption(opt, explanation, allowedValues, default):
- """ Allow the user to choose among a set of values for an option. This results in a commandline option with<Option>,
- where Option is the name of the option with a capitalized first letter.
- @param opt: The name of the option.
- @param explanation: Explanation of option.
- @param allowedValues: The set of values to choose from.
- @param default: The default value.
- """
- assert default in allowedValues
- return EnumOption("with%s" % opt[0].upper() + opt[1:], explanation, default, allowed_values=allowedValues)
-
-def _DirectoryOption(opt, explanation, default):
- """ Allow the user to configure the location for a certain directory, for instance the prefix. This results in a
- commandline option which is simply the name of this option.
- @param opt: The configurable directory, for instance "prefix".
- @param explanation: Explanation of option.
- @param default: The default value for this option.
- """
- return PathOption(opt, explanation, default)
- # Incompatible with the latest stable SCons
- # return PathOption(path, help, default, PathOption.PathIsDir)
-
-import SCons.Errors
-try:
- Import("Platform", "Posix")
-except SCons.Errors.UserError:
- # The common objects must be exported first
- SConscript("SConscript_common")
- Import("Platform", "Posix")
-
-# Expose the options as a dictionary of sets of options
-opts = {}
-
-if Platform in Posix:
- opts["Installation Dirs"] = [_DirectoryOption("prefix", "installation prefix", "/usr/local")]
-elif Platform in Windows:
- if Platform == "cygwin":
- opts["Installation Dirs"] = [_DirectoryOption("prefix", "installation prefix", "/usr/local")]
-
-opts["Build Targets"] = [_BoolOption("shared", "create shared library"), _BoolOption("static", "create static library"),
- _BoolOption("tests", "build test programs")]
-
-apis = []
-if Platform in Posix:
- apis.append(_PackageOption("OSS"))
- apis.append(_PackageOption("JACK"))
- apis.append(_PackageOption("ALSA", Platform == "linux"))
- apis.append(_PackageOption("ASIHPI", Platform == "linux"))
- apis.append(_PackageOption("COREAUDIO", Platform == "darwin"))
-elif Platform in Windows:
- if Platform == "cygwin":
- apis.append(_EnumOption("winAPI", "Windows API to use", ("wmme", "directx", "asio"), "wmme"))
-
-opts["Host APIs"] = apis
-
-opts["Build Parameters"] = [\
- _BoolOption("debug", "compile with debug symbols"),
- _BoolOption("optimize", "compile with optimization", default=0),
- _BoolOption("asserts", "runtime assertions are helpful for debugging, but can be detrimental to performance",
- default=1),
- _BoolOption("debugOutput", "enable debug output", default=0),
- # _BoolOption("python", "create Python binding"),
- ("customCFlags", "customize compilation of C code", ""),
- ("customCxxFlags", "customize compilation of C++ code", ""),
- ("customLinkFlags", "customize linking", ""),
- ]
-
-opts["Bindings"] = [\
- _BoolOption("cxx", "build Merlijn Blaauw's PA C++ wrapper", default=0)
- ]
-
-Return("opts")