removed vendor files from git, readded vscode config
This commit is contained in:
parent
92a9d2f0a9
commit
22adf8fe8a
27
vendor/bundle/bin/jekyll
vendored
27
vendor/bundle/bin/jekyll
vendored
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'jekyll' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('jekyll', 'jekyll', version)
|
||||
else
|
||||
gem "jekyll", version
|
||||
load Gem.bin_path("jekyll", "jekyll", version)
|
||||
end
|
27
vendor/bundle/bin/kramdown
vendored
27
vendor/bundle/bin/kramdown
vendored
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'kramdown' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('kramdown', 'kramdown', version)
|
||||
else
|
||||
gem "kramdown", version
|
||||
load Gem.bin_path("kramdown", "kramdown", version)
|
||||
end
|
27
vendor/bundle/bin/listen
vendored
27
vendor/bundle/bin/listen
vendored
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'listen' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('listen', 'listen', version)
|
||||
else
|
||||
gem "listen", version
|
||||
load Gem.bin_path("listen", "listen", version)
|
||||
end
|
27
vendor/bundle/bin/rougify
vendored
27
vendor/bundle/bin/rougify
vendored
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'rouge' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('rouge', 'rougify', version)
|
||||
else
|
||||
gem "rouge", version
|
||||
load Gem.bin_path("rouge", "rougify", version)
|
||||
end
|
27
vendor/bundle/bin/safe_yaml
vendored
27
vendor/bundle/bin/safe_yaml
vendored
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'safe_yaml' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('safe_yaml', 'safe_yaml', version)
|
||||
else
|
||||
gem "safe_yaml", version
|
||||
load Gem.bin_path("safe_yaml", "safe_yaml", version)
|
||||
end
|
BIN
vendor/bundle/cache/addressable-2.7.0.gem
vendored
BIN
vendor/bundle/cache/addressable-2.7.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/colorator-1.1.0.gem
vendored
BIN
vendor/bundle/cache/colorator-1.1.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/concurrent-ruby-1.1.5.gem
vendored
BIN
vendor/bundle/cache/concurrent-ruby-1.1.5.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/em-websocket-0.5.1.gem
vendored
BIN
vendor/bundle/cache/em-websocket-0.5.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/eventmachine-1.2.7.gem
vendored
BIN
vendor/bundle/cache/eventmachine-1.2.7.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/ffi-1.11.1.gem
vendored
BIN
vendor/bundle/cache/ffi-1.11.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/forwardable-extended-2.6.0.gem
vendored
BIN
vendor/bundle/cache/forwardable-extended-2.6.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/http_parser.rb-0.6.0.gem
vendored
BIN
vendor/bundle/cache/http_parser.rb-0.6.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/i18n-1.7.0.gem
vendored
BIN
vendor/bundle/cache/i18n-1.7.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/jekyll-4.0.0.gem
vendored
BIN
vendor/bundle/cache/jekyll-4.0.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/jekyll-feed-0.12.1.gem
vendored
BIN
vendor/bundle/cache/jekyll-feed-0.12.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/jekyll-sass-converter-2.0.1.gem
vendored
BIN
vendor/bundle/cache/jekyll-sass-converter-2.0.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/jekyll-seo-tag-2.6.1.gem
vendored
BIN
vendor/bundle/cache/jekyll-seo-tag-2.6.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/jekyll-watch-2.2.1.gem
vendored
BIN
vendor/bundle/cache/jekyll-watch-2.2.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/kramdown-2.1.0.gem
vendored
BIN
vendor/bundle/cache/kramdown-2.1.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/kramdown-parser-gfm-1.1.0.gem
vendored
BIN
vendor/bundle/cache/kramdown-parser-gfm-1.1.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/liquid-4.0.3.gem
vendored
BIN
vendor/bundle/cache/liquid-4.0.3.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/listen-3.2.0.gem
vendored
BIN
vendor/bundle/cache/listen-3.2.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/mercenary-0.3.6.gem
vendored
BIN
vendor/bundle/cache/mercenary-0.3.6.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/minima-2.5.1.gem
vendored
BIN
vendor/bundle/cache/minima-2.5.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/pathutil-0.16.2.gem
vendored
BIN
vendor/bundle/cache/pathutil-0.16.2.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/public_suffix-4.0.1.gem
vendored
BIN
vendor/bundle/cache/public_suffix-4.0.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/rb-fsevent-0.10.3.gem
vendored
BIN
vendor/bundle/cache/rb-fsevent-0.10.3.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/rb-inotify-0.10.0.gem
vendored
BIN
vendor/bundle/cache/rb-inotify-0.10.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/rouge-3.12.0.gem
vendored
BIN
vendor/bundle/cache/rouge-3.12.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/safe_yaml-1.0.5.gem
vendored
BIN
vendor/bundle/cache/safe_yaml-1.0.5.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/sassc-2.2.1.gem
vendored
BIN
vendor/bundle/cache/sassc-2.2.1.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/terminal-table-1.8.0.gem
vendored
BIN
vendor/bundle/cache/terminal-table-1.8.0.gem
vendored
Binary file not shown.
BIN
vendor/bundle/cache/unicode-display_width-1.6.0.gem
vendored
BIN
vendor/bundle/cache/unicode-display_width-1.6.0.gem
vendored
Binary file not shown.
Binary file not shown.
@ -1,16 +0,0 @@
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/eventmachine-1.2.7/ext/fastfilereader
|
||||
/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/bin/ruby -I /Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0 -r ./siteconf20191020-69875-moqdwe.rb extconf.rb
|
||||
creating Makefile
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/eventmachine-1.2.7/ext/fastfilereader
|
||||
make "DESTDIR=" clean
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/eventmachine-1.2.7/ext/fastfilereader
|
||||
make "DESTDIR="
|
||||
compiling mapper.cpp
|
||||
compiling rubymain.cpp
|
||||
linking shared-object fastfilereaderext.bundle
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/eventmachine-1.2.7/ext/fastfilereader
|
||||
make "DESTDIR=" install
|
||||
/usr/local/opt/coreutils/bin/ginstall -c -m 0755 fastfilereaderext.bundle ./.gem.20191020-69875-rb74yq
|
@ -1,11 +0,0 @@
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: int main(int argc, char **argv)
|
||||
4: {
|
||||
5: return 0;
|
||||
6: }
|
||||
/* end */
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,128 +0,0 @@
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c
|
||||
/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/bin/ruby -I /Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0 -r ./siteconf20191020-69875-r3jdpp.rb extconf.rb
|
||||
checking for ffi.h... no
|
||||
checking for ffi.h in /usr/local/include,/usr/include/ffi... no
|
||||
checking for shlwapi.h... no
|
||||
checking for rb_thread_call_without_gvl()... yes
|
||||
checking for ruby_native_thread_p()... yes
|
||||
checking for ruby_thread_has_gvl_p()... yes
|
||||
creating extconf.h
|
||||
creating Makefile
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c
|
||||
make "DESTDIR=" clean
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c
|
||||
make "DESTDIR="
|
||||
Configuring libffi
|
||||
clang: error: unsupported option '-print-multi-os-directory'
|
||||
clang: error: no input files
|
||||
cd "/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi-x86_64-darwin18" && /Applications/Xcode.app/Contents/Developer/usr/bin/make
|
||||
/Applications/Xcode.app/Contents/Developer/usr/bin/make 'AR_FLAGS=' 'CC_FOR_BUILD=' 'CFLAGS=-Wall -fexceptions' 'CXXFLAGS=-g -O2' 'CFLAGS_FOR_BUILD=' 'CFLAGS_FOR_TARGET=' 'INSTALL=/usr/local/bin/ginstall -c' 'INSTALL_DATA=/usr/local/bin/ginstall -c -m 644' 'INSTALL_PROGRAM=/usr/local/bin/ginstall -c' 'INSTALL_SCRIPT=/usr/local/bin/ginstall -c' 'JC1FLAGS=' 'LDFLAGS=' 'LIBCFLAGS=' 'LIBCFLAGS_FOR_TARGET=' 'MAKE=/Applications/Xcode.app/Contents/Developer/usr/bin/make' 'MAKEINFO=/bin/sh /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/missing makeinfo ' 'PICFLAG=' 'PICFLAG_FOR_TARGET=' 'RUNTESTFLAGS=' 'SHELL=/bin/sh' 'exec_prefix=/usr/local' 'infodir=/usr/local/share/info' 'libdir=/usr/local/lib' 'mandir=/usr/local/share/man' 'prefix=/usr/local' 'AR=ar' 'AS=as' 'CC=gcc' 'CXX=g++' 'LD=ld' 'NM=/usr/bin/nm -B' 'RANLIB=ranlib' 'DESTDIR=' all-recursive
|
||||
Making all in include
|
||||
make[3]: Nothing to be done for `all'.
|
||||
Making all in testsuite
|
||||
make[3]: Nothing to be done for `all'.
|
||||
Making all in man
|
||||
make[3]: Nothing to be done for `all'.
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/prep_cif.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/prep_cif.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/prep_cif.c -fno-common -DPIC -o src/.libs/prep_cif.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/types.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/types.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/types.c -fno-common -DPIC -o src/.libs/types.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/raw_api.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/raw_api.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/raw_api.c -fno-common -DPIC -o src/.libs/raw_api.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/java_raw_api.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/java_raw_api.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/java_raw_api.c -fno-common -DPIC -o src/.libs/java_raw_api.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/closures.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/closures.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/closures.c -fno-common -DPIC -o src/.libs/closures.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/x86/ffi64.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/ffi64.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/ffi64.c -fno-common -DPIC -o src/x86/.libs/ffi64.o
|
||||
/bin/sh ./libtool --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -c -o src/x86/unix64.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/unix64.S
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/unix64.S -fno-common -DPIC -o src/x86/.libs/unix64.o
|
||||
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c -o src/x86/ffiw64.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/ffiw64.c
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/ffiw64.c -fno-common -DPIC -o src/x86/.libs/ffiw64.o
|
||||
/bin/sh ./libtool --mode=compile gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -c -o src/x86/win64.lo /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/win64.S
|
||||
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -I. -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/include -Iinclude -I/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src -c /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/src/x86/win64.S -fno-common -DPIC -o src/x86/.libs/win64.o
|
||||
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -fexceptions -o libffi_convenience.la src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffiw64.lo src/x86/win64.lo
|
||||
libtool: link: ar cru .libs/libffi_convenience.a src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffiw64.o src/x86/.libs/win64.o
|
||||
libtool: link: ranlib .libs/libffi_convenience.a
|
||||
libtool: link: ( cd ".libs" && rm -f "libffi_convenience.la" && ln -s "../libffi_convenience.la" "libffi_convenience.la" )
|
||||
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -fexceptions -no-undefined -version-info `grep -v '^#' /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/libtool-version` -o libffi.la -rpath /usr/local/lib src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffiw64.lo src/x86/win64.lo
|
||||
libtool: link: gcc -dynamiclib -o .libs/libffi.7.dylib src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffiw64.o src/x86/.libs/win64.o -install_name /usr/local/lib/libffi.7.dylib -compatibility_version 9 -current_version 9.0 -Wl,-single_module
|
||||
libtool: link: (cd ".libs" && rm -f "libffi.dylib" && ln -s "libffi.7.dylib" "libffi.dylib")
|
||||
libtool: link: ( cd ".libs" && rm -f "libffi.la" && ln -s "../libffi.la" "libffi.la" )
|
||||
compiling AbstractMemory.c
|
||||
compiling ArrayType.c
|
||||
compiling Buffer.c
|
||||
compiling Call.c
|
||||
compiling ClosurePool.c
|
||||
compiling DynamicLibrary.c
|
||||
compiling Function.c
|
||||
Function.c:867:17: warning: 'ffi_prep_closure' is deprecated [-Wdeprecated-declarations]
|
||||
ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
|
||||
^
|
||||
/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi-x86_64-darwin18/include/ffi.h:339:18: note: 'ffi_prep_closure' has been explicitly marked deprecated here
|
||||
__attribute__((deprecated))
|
||||
^
|
||||
1 warning generated.
|
||||
compiling FunctionInfo.c
|
||||
compiling LastError.c
|
||||
compiling LongDouble.c
|
||||
compiling MappedType.c
|
||||
compiling MemoryPointer.c
|
||||
compiling MethodHandle.c
|
||||
compiling Platform.c
|
||||
compiling Pointer.c
|
||||
compiling Struct.c
|
||||
compiling StructByValue.c
|
||||
compiling StructLayout.c
|
||||
compiling Thread.c
|
||||
compiling Type.c
|
||||
compiling Types.c
|
||||
compiling Variadic.c
|
||||
compiling ffi.c
|
||||
linking shared-object ffi_c.bundle
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c
|
||||
make "DESTDIR=" install
|
||||
cd "/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi-x86_64-darwin18" && /Applications/Xcode.app/Contents/Developer/usr/bin/make
|
||||
/Applications/Xcode.app/Contents/Developer/usr/bin/make 'AR_FLAGS=' 'CC_FOR_BUILD=' 'CFLAGS=-Wall -fexceptions' 'CXXFLAGS=-g -O2' 'CFLAGS_FOR_BUILD=' 'CFLAGS_FOR_TARGET=' 'INSTALL=/usr/local/bin/ginstall -c' 'INSTALL_DATA=/usr/local/bin/ginstall -c -m 644' 'INSTALL_PROGRAM=/usr/local/bin/ginstall -c' 'INSTALL_SCRIPT=/usr/local/bin/ginstall -c' 'JC1FLAGS=' 'LDFLAGS=' 'LIBCFLAGS=' 'LIBCFLAGS_FOR_TARGET=' 'MAKE=/Applications/Xcode.app/Contents/Developer/usr/bin/make' 'MAKEINFO=/bin/sh /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi/missing makeinfo ' 'PICFLAG=' 'PICFLAG_FOR_TARGET=' 'RUNTESTFLAGS=' 'SHELL=/bin/sh' 'exec_prefix=/usr/local' 'infodir=/usr/local/share/info' 'libdir=/usr/local/lib' 'mandir=/usr/local/share/man' 'prefix=/usr/local' 'AR=ar' 'AS=as' 'CC=gcc' 'CXX=g++' 'LD=ld' 'NM=/usr/bin/nm -B' 'RANLIB=ranlib' 'DESTDIR=' all-recursive
|
||||
Making all in include
|
||||
make[3]: Nothing to be done for `all'.
|
||||
Making all in testsuite
|
||||
make[3]: Nothing to be done for `all'.
|
||||
Making all in man
|
||||
make[3]: Nothing to be done for `all'.
|
||||
make[3]: Nothing to be done for `all-am'.
|
||||
compiling AbstractMemory.c
|
||||
compiling ArrayType.c
|
||||
compiling Buffer.c
|
||||
compiling Call.c
|
||||
compiling ClosurePool.c
|
||||
compiling DynamicLibrary.c
|
||||
compiling Function.c
|
||||
Function.c:867:17: warning: 'ffi_prep_closure' is deprecated [-Wdeprecated-declarations]
|
||||
ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
|
||||
^
|
||||
/Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/ffi-1.11.1/ext/ffi_c/libffi-x86_64-darwin18/include/ffi.h:339:18: note: 'ffi_prep_closure' has been explicitly marked deprecated here
|
||||
__attribute__((deprecated))
|
||||
^
|
||||
1 warning generated.
|
||||
compiling FunctionInfo.c
|
||||
compiling LastError.c
|
||||
compiling LongDouble.c
|
||||
compiling MappedType.c
|
||||
compiling MemoryPointer.c
|
||||
compiling MethodHandle.c
|
||||
compiling Platform.c
|
||||
compiling Pointer.c
|
||||
compiling Struct.c
|
||||
compiling StructByValue.c
|
||||
compiling StructLayout.c
|
||||
compiling Thread.c
|
||||
compiling Type.c
|
||||
compiling Types.c
|
||||
compiling Variadic.c
|
||||
compiling ffi.c
|
||||
linking shared-object ffi_c.bundle
|
||||
/usr/local/opt/coreutils/bin/ginstall -c -m 0755 ffi_c.bundle ./.gem.20191020-69875-3w418n
|
@ -1,215 +0,0 @@
|
||||
"pkg-config --exists libffi"
|
||||
package configuration for libffi is not found
|
||||
have_header: checking for ffi.h... -------------------- no
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: int main(int argc, char **argv)
|
||||
4: {
|
||||
5: return 0;
|
||||
6: }
|
||||
/* end */
|
||||
|
||||
"gcc -E -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -o conftest.i"
|
||||
conftest.c:3:10: fatal error: 'ffi.h' file not found
|
||||
#include <ffi.h>
|
||||
^~~~~~~
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: #include <ffi.h>
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
find_header: checking for ffi.h in /usr/local/include,/usr/include/ffi... -------------------- no
|
||||
|
||||
"gcc -E -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -o conftest.i"
|
||||
conftest.c:3:10: fatal error: 'ffi.h' file not found
|
||||
#include <ffi.h>
|
||||
^~~~~~~
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: #include <ffi.h>
|
||||
/* end */
|
||||
|
||||
"gcc -E -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe -I/usr/local/include conftest.c -o conftest.i"
|
||||
conftest.c:3:10: fatal error: 'ffi.h' file not found
|
||||
#include <ffi.h>
|
||||
^~~~~~~
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: #include <ffi.h>
|
||||
/* end */
|
||||
|
||||
"gcc -E -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe -I/usr/include/ffi conftest.c -o conftest.i"
|
||||
conftest.c:3:10: fatal error: 'ffi.h' file not found
|
||||
#include <ffi.h>
|
||||
^~~~~~~
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: #include <ffi.h>
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
have_header: checking for shlwapi.h... -------------------- no
|
||||
|
||||
"gcc -E -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -o conftest.i"
|
||||
conftest.c:3:10: fatal error: 'shlwapi.h' file not found
|
||||
#include <shlwapi.h>
|
||||
^~~~~~~~~~~
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: #include <shlwapi.h>
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
have_func: checking for rb_thread_call_without_gvl()... -------------------- yes
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
conftest.c:14:57: error: use of undeclared identifier 'rb_thread_call_without_gvl'
|
||||
int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_without_gvl; return !p; }
|
||||
^
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: /*top*/
|
||||
4: extern int t(void);
|
||||
5: int main(int argc, char **argv)
|
||||
6: {
|
||||
7: if (argc > 1000000) {
|
||||
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
||||
9: printf("%d", (*tp)());
|
||||
10: }
|
||||
11:
|
||||
12: return 0;
|
||||
13: }
|
||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_without_gvl; return !p; }
|
||||
/* end */
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: /*top*/
|
||||
4: extern int t(void);
|
||||
5: int main(int argc, char **argv)
|
||||
6: {
|
||||
7: if (argc > 1000000) {
|
||||
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
||||
9: printf("%d", (*tp)());
|
||||
10: }
|
||||
11:
|
||||
12: return 0;
|
||||
13: }
|
||||
14: extern void rb_thread_call_without_gvl();
|
||||
15: int t(void) { rb_thread_call_without_gvl(); return 0; }
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
have_func: checking for ruby_native_thread_p()... -------------------- yes
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: /*top*/
|
||||
4: extern int t(void);
|
||||
5: int main(int argc, char **argv)
|
||||
6: {
|
||||
7: if (argc > 1000000) {
|
||||
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
||||
9: printf("%d", (*tp)());
|
||||
10: }
|
||||
11:
|
||||
12: return 0;
|
||||
13: }
|
||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ruby_native_thread_p; return !p; }
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
have_func: checking for ruby_thread_has_gvl_p()... -------------------- yes
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
conftest.c:14:57: error: use of undeclared identifier 'ruby_thread_has_gvl_p'
|
||||
int t(void) { void ((*volatile p)()); p = (void ((*)()))ruby_thread_has_gvl_p; return !p; }
|
||||
^
|
||||
1 error generated.
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: /*top*/
|
||||
4: extern int t(void);
|
||||
5: int main(int argc, char **argv)
|
||||
6: {
|
||||
7: if (argc > 1000000) {
|
||||
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
||||
9: printf("%d", (*tp)());
|
||||
10: }
|
||||
11:
|
||||
12: return 0;
|
||||
13: }
|
||||
14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ruby_thread_has_gvl_p; return !p; }
|
||||
/* end */
|
||||
|
||||
"gcc -o conftest -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/x86_64-darwin18 -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0/ruby/backward -I/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/include/ruby-2.6.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/libksba/include -I/usr/local/opt/readline/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/zlib/lib -L/usr/local/opt/openssl@1.1/lib -lruby.2.6 "
|
||||
checked program was:
|
||||
/* begin */
|
||||
1: #include "ruby.h"
|
||||
2:
|
||||
3: /*top*/
|
||||
4: extern int t(void);
|
||||
5: int main(int argc, char **argv)
|
||||
6: {
|
||||
7: if (argc > 1000000) {
|
||||
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
||||
9: printf("%d", (*tp)());
|
||||
10: }
|
||||
11:
|
||||
12: return 0;
|
||||
13: }
|
||||
14: extern void ruby_thread_has_gvl_p();
|
||||
15: int t(void) { ruby_thread_has_gvl_p(); return 0; }
|
||||
/* end */
|
||||
|
||||
--------------------
|
||||
|
||||
extconf.h is:
|
||||
/* begin */
|
||||
1: #ifndef EXTCONF_H
|
||||
2: #define EXTCONF_H
|
||||
3: #define HAVE_RB_THREAD_CALL_WITHOUT_GVL 1
|
||||
4: #define HAVE_RUBY_NATIVE_THREAD_P 1
|
||||
5: #define HAVE_RUBY_THREAD_HAS_GVL_P 1
|
||||
6: #define HAVE_FFI_PREP_CIF_VAR 1
|
||||
7: #define USE_INTERNAL_LIBFFI 1
|
||||
8: #define RUBY_1_9 1
|
||||
9: #endif
|
||||
/* end */
|
||||
|
@ -1,16 +0,0 @@
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
|
||||
/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/bin/ruby -I /Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0 -r ./siteconf20191020-69875-15g4lcd.rb extconf.rb
|
||||
creating Makefile
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
|
||||
make "DESTDIR=" clean
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
|
||||
make "DESTDIR="
|
||||
compiling ruby_http_parser.c
|
||||
compiling ryah_http_parser.c
|
||||
linking shared-object ruby_http_parser.bundle
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
|
||||
make "DESTDIR=" install
|
||||
/usr/local/opt/coreutils/bin/ginstall -c -m 0755 ruby_http_parser.bundle ./.gem.20191020-69875-2pn1qv
|
Binary file not shown.
@ -1,75 +0,0 @@
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/sassc-2.2.1/ext
|
||||
/Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/bin/ruby -I /Users/BenjaminJones/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0 -r ./siteconf20191020-69875-10qd776.rb extconf.rb
|
||||
creating Makefile
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/sassc-2.2.1/ext
|
||||
make "DESTDIR=" clean
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/sassc-2.2.1/ext
|
||||
make "DESTDIR="
|
||||
compiling ./libsass/src/units.cpp
|
||||
compiling ./libsass/src/fn_miscs.cpp
|
||||
compiling ./libsass/src/util.cpp
|
||||
compiling ./libsass/src/ast_selectors.cpp
|
||||
compiling ./libsass/src/environment.cpp
|
||||
compiling ./libsass/src/memory/SharedPtr.cpp
|
||||
compiling ./libsass/src/ast_sel_unify.cpp
|
||||
compiling ./libsass/src/ast.cpp
|
||||
compiling ./libsass/src/emitter.cpp
|
||||
compiling ./libsass/src/bind.cpp
|
||||
compiling ./libsass/src/sass_functions.cpp
|
||||
compiling ./libsass/src/ast2c.cpp
|
||||
compiling ./libsass/src/base64vlq.cpp
|
||||
compiling ./libsass/src/context.cpp
|
||||
compiling ./libsass/src/remove_placeholders.cpp
|
||||
compiling ./libsass/src/node.cpp
|
||||
compiling ./libsass/src/fn_colors.cpp
|
||||
compiling ./libsass/src/sass_values.cpp
|
||||
compiling ./libsass/src/constants.cpp
|
||||
compiling ./libsass/src/ast_values.cpp
|
||||
compiling ./libsass/src/lexer.cpp
|
||||
compiling ./libsass/src/color_maps.cpp
|
||||
compiling ./libsass/src/fn_selectors.cpp
|
||||
compiling ./libsass/src/fn_numbers.cpp
|
||||
compiling ./libsass/src/operators.cpp
|
||||
compiling ./libsass/src/output.cpp
|
||||
compiling ./libsass/src/source_map.cpp
|
||||
compiling ./libsass/src/sass.cpp
|
||||
compiling ./libsass/src/listize.cpp
|
||||
compiling ./libsass/src/ast_fwd_decl.cpp
|
||||
compiling ./libsass/src/sass_util.cpp
|
||||
compiling ./libsass/src/fn_strings.cpp
|
||||
compiling ./libsass/src/fn_utils.cpp
|
||||
compiling ./libsass/src/ast_sel_cmp.cpp
|
||||
compiling ./libsass/src/fn_maps.cpp
|
||||
compiling ./libsass/src/file.cpp
|
||||
compiling ./libsass/src/c99func.c
|
||||
compiling ./libsass/src/ast_supports.cpp
|
||||
compiling ./libsass/src/check_nesting.cpp
|
||||
compiling ./libsass/src/inspect.cpp
|
||||
compiling ./libsass/src/extend.cpp
|
||||
compiling ./libsass/src/plugins.cpp
|
||||
compiling ./libsass/src/cssize.cpp
|
||||
compiling ./libsass/src/sass2scss.cpp
|
||||
compiling ./libsass/src/to_value.cpp
|
||||
compiling ./libsass/src/prelexer.cpp
|
||||
compiling ./libsass/src/subset_map.cpp
|
||||
compiling ./libsass/src/utf8_string.cpp
|
||||
compiling ./libsass/src/backtrace.cpp
|
||||
compiling ./libsass/src/json.cpp
|
||||
compiling ./libsass/src/parser.cpp
|
||||
compiling ./libsass/src/util_string.cpp
|
||||
compiling ./libsass/src/error_handling.cpp
|
||||
compiling ./libsass/src/sass_context.cpp
|
||||
compiling ./libsass/src/eval.cpp
|
||||
compiling ./libsass/src/values.cpp
|
||||
compiling ./libsass/src/cencode.c
|
||||
compiling ./libsass/src/fn_lists.cpp
|
||||
compiling ./libsass/src/position.cpp
|
||||
compiling ./libsass/src/expand.cpp
|
||||
compiling ./libsass/src/c2ast.cpp
|
||||
linking shared-object sassc/libsass.bundle
|
||||
|
||||
current directory: /Users/BenjaminJones/Documents/Code/ReclaimFutures/rf-web/vendor/bundle/gems/sassc-2.2.1/ext
|
||||
make "DESTDIR=" install
|
||||
/usr/local/opt/coreutils/bin/ginstall -c -m 0755 libsass.bundle ./.gem.20191020-69875-1kuo96p/sassc
|
Binary file not shown.
235
vendor/bundle/gems/addressable-2.7.0/CHANGELOG.md
vendored
235
vendor/bundle/gems/addressable-2.7.0/CHANGELOG.md
vendored
@ -1,235 +0,0 @@
|
||||
# Addressable 2.7.0
|
||||
- added `:compacted` flag to `normalized_query`
|
||||
- `heuristic_parse` handles `mailto:` more intuitively
|
||||
- refactored validation to use a prepended module
|
||||
- dropped explicit support for JRuby 9.0.5.0
|
||||
- compatibility w/ public_suffix 4.x
|
||||
- performance improvements
|
||||
|
||||
# Addressable 2.6.0
|
||||
- added `tld=` method to allow assignment to the public suffix
|
||||
- most `heuristic_parse` patterns are now case-insensitive
|
||||
- `heuristic_parse` handles more `file://` URI variations
|
||||
- fixes bug in `heuristic_parse` when uri starts with digit
|
||||
- fixes bug in `request_uri=` with query strings
|
||||
- fixes template issues with `nil` and `?` operator
|
||||
- `frozen_string_literal` pragmas added
|
||||
- minor performance improvements in regexps
|
||||
- fixes to eliminate warnings
|
||||
|
||||
# Addressable 2.5.2
|
||||
- better support for frozen string literals
|
||||
- fixed bug w/ uppercase characters in scheme
|
||||
- IDNA errors w/ emoji URLs
|
||||
- compatibility w/ public_suffix 3.x
|
||||
|
||||
# Addressable 2.5.1
|
||||
- allow unicode normalization to be disabled for URI Template expansion
|
||||
- removed duplicate test
|
||||
|
||||
# Addressable 2.5.0
|
||||
- dropping support for Ruby 1.9
|
||||
- adding support for Ruby 2.4 preview
|
||||
- add support for public suffixes and tld; first runtime dependency
|
||||
- hostname escaping should match RFC; underscores in hostnames no longer escaped
|
||||
- paths beginning with // and missing an authority are now considered invalid
|
||||
- validation now also takes place after setting a path
|
||||
- handle backslashes in authority more like a browser for `heuristic_parse`
|
||||
- unescaped backslashes in host now raise an `InvalidURIError`
|
||||
- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation
|
||||
- `heuristic_parse` now trims whitespace before parsing
|
||||
- host parts longer than 63 bytes will be ignored and not passed to libidn
|
||||
- normalized values always encoded as UTF-8
|
||||
|
||||
# Addressable 2.4.0
|
||||
- support for 1.8.x dropped
|
||||
- double quotes in a host now raises an error
|
||||
- newlines in host will no longer get unescaped during normalization
|
||||
- stricter handling of bogus scheme values
|
||||
- stricter handling of encoded port values
|
||||
- calling `require 'addressable'` will now load both the URI and Template files
|
||||
- assigning to the `hostname` component with an `IPAddr` object is now supported
|
||||
- assigning to the `origin` component is now supported
|
||||
- fixed minor bug where an exception would be thrown for a missing ACE suffix
|
||||
- better partial expansion of URI templates
|
||||
|
||||
# Addressable 2.3.8
|
||||
- fix warnings
|
||||
- update dependency gems
|
||||
- support for 1.8.x officially deprecated
|
||||
|
||||
# Addressable 2.3.7
|
||||
- fix scenario in which invalid URIs don't get an exception until inspected
|
||||
- handle hostnames with two adjacent periods correctly
|
||||
- upgrade of RSpec
|
||||
|
||||
# Addressable 2.3.6
|
||||
- normalization drops empty query string
|
||||
- better handling in template extract for missing values
|
||||
- template modifier for `'?'` now treated as optional
|
||||
- fixed issue where character class parameters were modified
|
||||
- templates can now be tested for equality
|
||||
- added `:sorted` option to normalization of query strings
|
||||
- fixed issue with normalization of hosts given in `'example.com.'` form
|
||||
|
||||
# Addressable 2.3.5
|
||||
- added Addressable::URI#empty? method
|
||||
- Addressable::URI#hostname methods now strip square brackets from IPv6 hosts
|
||||
- compatibility with Net::HTTP in Ruby 2.0.0
|
||||
- Addressable::URI#route_from should always give relative URIs
|
||||
|
||||
# Addressable 2.3.4
|
||||
- fixed issue with encoding altering its inputs
|
||||
- query string normalization now leaves ';' characters alone
|
||||
- FakeFS is detected before attempting to load unicode tables
|
||||
- additional testing to ensure frozen objects don't cause problems
|
||||
|
||||
# Addressable 2.3.3
|
||||
- fixed issue with converting common primitives during template expansion
|
||||
- fixed port encoding issue
|
||||
- removed a few warnings
|
||||
- normalize should now ignore %2B in query strings
|
||||
- the IDNA logic should now be handled by libidn in Ruby 1.9
|
||||
- no template match should now result in nil instead of an empty MatchData
|
||||
- added license information to gemspec
|
||||
|
||||
# Addressable 2.3.2
|
||||
- added Addressable::URI#default_port method
|
||||
- fixed issue with Marshalling Unicode data on Windows
|
||||
- improved heuristic parsing to better handle IPv4 addresses
|
||||
|
||||
# Addressable 2.3.1
|
||||
- fixed missing unicode data file
|
||||
|
||||
# Addressable 2.3.0
|
||||
- updated Addressable::Template to use RFC 6570, level 4
|
||||
- fixed compatibility problems with some versions of Ruby
|
||||
- moved unicode tables into a data file for performance reasons
|
||||
- removing support for multiple query value notations
|
||||
|
||||
# Addressable 2.2.8
|
||||
- fixed issues with dot segment removal code
|
||||
- form encoding can now handle multiple values per key
|
||||
- updated development environment
|
||||
|
||||
# Addressable 2.2.7
|
||||
- fixed issues related to Addressable::URI#query_values=
|
||||
- the Addressable::URI.parse method is now polymorphic
|
||||
|
||||
# Addressable 2.2.6
|
||||
- changed the way ambiguous paths are handled
|
||||
- fixed bug with frozen URIs
|
||||
- https supported in heuristic parsing
|
||||
|
||||
# Addressable 2.2.5
|
||||
- 'parsing' a pre-parsed URI object is now a dup operation
|
||||
- introduced conditional support for libidn
|
||||
- fixed normalization issue on ampersands in query strings
|
||||
- added additional tests around handling of query strings
|
||||
|
||||
# Addressable 2.2.4
|
||||
- added origin support from draft-ietf-websec-origin-00
|
||||
- resolved issue with attempting to navigate below root
|
||||
- fixed bug with string splitting in query strings
|
||||
|
||||
# Addressable 2.2.3
|
||||
- added :flat_array notation for query strings
|
||||
|
||||
# Addressable 2.2.2
|
||||
- fixed issue with percent escaping of '+' character in query strings
|
||||
|
||||
# Addressable 2.2.1
|
||||
- added support for application/x-www-form-urlencoded.
|
||||
|
||||
# Addressable 2.2.0
|
||||
- added site methods
|
||||
- improved documentation
|
||||
|
||||
# Addressable 2.1.2
|
||||
- added HTTP request URI methods
|
||||
- better handling of Windows file paths
|
||||
- validation_deferred boolean replaced with defer_validation block
|
||||
- normalization of percent-encoded paths should now be correct
|
||||
- fixed issue with constructing URIs with relative paths
|
||||
- fixed warnings
|
||||
|
||||
# Addressable 2.1.1
|
||||
- more type checking changes
|
||||
- fixed issue with unicode normalization
|
||||
- added method to find template defaults
|
||||
- symbolic keys are now allowed in template mappings
|
||||
- numeric values and symbolic values are now allowed in template mappings
|
||||
|
||||
# Addressable 2.1.0
|
||||
- refactored URI template support out into its own class
|
||||
- removed extract method due to being useless and unreliable
|
||||
- removed Addressable::URI.expand_template
|
||||
- removed Addressable::URI#extract_mapping
|
||||
- added partial template expansion
|
||||
- fixed minor bugs in the parse and heuristic_parse methods
|
||||
- fixed incompatibility with Ruby 1.9.1
|
||||
- fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s
|
||||
- fixed unicode normalization exception
|
||||
- updated query_values methods to better handle subscript notation
|
||||
- worked around issue with freezing URIs
|
||||
- improved specs
|
||||
|
||||
# Addressable 2.0.2
|
||||
- fixed issue with URI template expansion
|
||||
- fixed issue with percent escaping characters 0-15
|
||||
|
||||
# Addressable 2.0.1
|
||||
- fixed issue with query string assignment
|
||||
- fixed issue with improperly encoded components
|
||||
|
||||
# Addressable 2.0.0
|
||||
- the initialize method now takes an options hash as its only parameter
|
||||
- added query_values method to URI class
|
||||
- completely replaced IDNA implementation with pure Ruby
|
||||
- renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION
|
||||
- completely reworked the Rakefile
|
||||
- changed the behavior of the port method significantly
|
||||
- Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed
|
||||
- documentation is now in YARD format
|
||||
- more rigorous type checking
|
||||
- to_str method implemented, implicit conversion to Strings now allowed
|
||||
- Addressable::URI#omit method added, Addressable::URI#merge method replaced
|
||||
- updated URI Template code to match v 03 of the draft spec
|
||||
- added a bunch of new specifications
|
||||
|
||||
# Addressable 1.0.4
|
||||
- switched to using RSpec's pending system for specs that rely on IDN
|
||||
- fixed issue with creating URIs with paths that are not prefixed with '/'
|
||||
|
||||
# Addressable 1.0.3
|
||||
- implemented a hash method
|
||||
|
||||
# Addressable 1.0.2
|
||||
- fixed minor bug with the extract_mapping method
|
||||
|
||||
# Addressable 1.0.1
|
||||
- fixed minor bug with the extract_mapping method
|
||||
|
||||
# Addressable 1.0.0
|
||||
- heuristic parse method added
|
||||
- parsing is slightly more strict
|
||||
- replaced to_h with to_hash
|
||||
- fixed routing methods
|
||||
- improved specifications
|
||||
- improved heckle rake task
|
||||
- no surviving heckle mutations
|
||||
|
||||
# Addressable 0.1.2
|
||||
- improved normalization
|
||||
- fixed bug in joining algorithm
|
||||
- updated specifications
|
||||
|
||||
# Addressable 0.1.1
|
||||
- updated documentation
|
||||
- added URI Template variable extraction
|
||||
|
||||
# Addressable 0.1.0
|
||||
- initial release
|
||||
- implementation based on RFC 3986, 3987
|
||||
- support for IRIs via libidn
|
||||
- support for the URI Template draft spec
|
32
vendor/bundle/gems/addressable-2.7.0/Gemfile
vendored
32
vendor/bundle/gems/addressable-2.7.0/Gemfile
vendored
@ -1,32 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gemspec
|
||||
|
||||
group :test do
|
||||
gem 'rspec', '~> 3.8'
|
||||
gem 'rspec-its', '~> 1.3'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'launchy', '~> 2.4', '>= 2.4.3'
|
||||
gem 'redcarpet', :platform => :mri_19
|
||||
gem 'yard'
|
||||
end
|
||||
|
||||
group :test, :development do
|
||||
gem 'rake', '> 10.0', '< 12'
|
||||
gem 'simplecov', :require => false
|
||||
gem 'coveralls', :require => false, :platforms => [
|
||||
:ruby_20, :ruby_21, :ruby_22, :ruby_23
|
||||
]
|
||||
# Used to test compatibility.
|
||||
gem 'rack-mount', git: 'https://github.com/sporkmonger/rack-mount.git', require: 'rack/mount'
|
||||
|
||||
if RUBY_VERSION.start_with?('2.0', '2.1')
|
||||
gem 'rack', '< 2', :require => false
|
||||
else
|
||||
gem 'rack', :require => false
|
||||
end
|
||||
end
|
||||
|
||||
gem 'idn-ruby', :platform => [:mri_20, :mri_21, :mri_22, :mri_23, :mri_24]
|
202
vendor/bundle/gems/addressable-2.7.0/LICENSE.txt
vendored
202
vendor/bundle/gems/addressable-2.7.0/LICENSE.txt
vendored
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
121
vendor/bundle/gems/addressable-2.7.0/README.md
vendored
121
vendor/bundle/gems/addressable-2.7.0/README.md
vendored
@ -1,121 +0,0 @@
|
||||
# Addressable
|
||||
|
||||
<dl>
|
||||
<dt>Homepage</dt><dd><a href="https://github.com/sporkmonger/addressable">github.com/sporkmonger/addressable</a></dd>
|
||||
<dt>Author</dt><dd><a href="mailto:bob@sporkmonger.com">Bob Aman</a></dd>
|
||||
<dt>Copyright</dt><dd>Copyright © Bob Aman</dd>
|
||||
<dt>License</dt><dd>Apache 2.0</dd>
|
||||
</dl>
|
||||
|
||||
[![Gem Version](http://img.shields.io/gem/dt/addressable.svg)][gem]
|
||||
[![Build Status](https://secure.travis-ci.org/sporkmonger/addressable.svg?branch=master)][travis]
|
||||
[![Test Coverage Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls]
|
||||
[![Documentation Coverage Status](http://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch]
|
||||
|
||||
[gem]: https://rubygems.org/gems/addressable
|
||||
[travis]: http://travis-ci.org/sporkmonger/addressable
|
||||
[coveralls]: https://coveralls.io/r/sporkmonger/addressable
|
||||
[inch]: http://inch-ci.org/github/sporkmonger/addressable
|
||||
|
||||
# Description
|
||||
|
||||
Addressable is an alternative implementation to the URI implementation
|
||||
that is part of Ruby's standard library. It is flexible, offers heuristic
|
||||
parsing, and additionally provides extensive support for IRIs and URI templates.
|
||||
|
||||
Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4).
|
||||
|
||||
# Reference
|
||||
|
||||
- {Addressable::URI}
|
||||
- {Addressable::Template}
|
||||
|
||||
# Example usage
|
||||
|
||||
```ruby
|
||||
require "addressable/uri"
|
||||
|
||||
uri = Addressable::URI.parse("http://example.com/path/to/resource/")
|
||||
uri.scheme
|
||||
#=> "http"
|
||||
uri.host
|
||||
#=> "example.com"
|
||||
uri.path
|
||||
#=> "/path/to/resource/"
|
||||
|
||||
uri = Addressable::URI.parse("http://www.詹姆斯.com/")
|
||||
uri.normalize
|
||||
#=> #<Addressable::URI:0xc9a4c8 URI:http://www.xn--8ws00zhy3a.com/>
|
||||
```
|
||||
|
||||
|
||||
# URI Templates
|
||||
|
||||
For more details, see [RFC 6570](https://www.rfc-editor.org/rfc/rfc6570.txt).
|
||||
|
||||
|
||||
```ruby
|
||||
|
||||
require "addressable/template"
|
||||
|
||||
template = Addressable::Template.new("http://example.com/{?query*}")
|
||||
template.expand({
|
||||
"query" => {
|
||||
'foo' => 'bar',
|
||||
'color' => 'red'
|
||||
}
|
||||
})
|
||||
#=> #<Addressable::URI:0xc9d95c URI:http://example.com/?foo=bar&color=red>
|
||||
|
||||
template = Addressable::Template.new("http://example.com/{?one,two,three}")
|
||||
template.partial_expand({"one" => "1", "three" => 3}).pattern
|
||||
#=> "http://example.com/?one=1{&two}&three=3"
|
||||
|
||||
template = Addressable::Template.new(
|
||||
"http://{host}{/segments*}/{?one,two,bogus}{#fragment}"
|
||||
)
|
||||
uri = Addressable::URI.parse(
|
||||
"http://example.com/a/b/c/?one=1&two=2#foo"
|
||||
)
|
||||
template.extract(uri)
|
||||
#=>
|
||||
# {
|
||||
# "host" => "example.com",
|
||||
# "segments" => ["a", "b", "c"],
|
||||
# "one" => "1",
|
||||
# "two" => "2",
|
||||
# "fragment" => "foo"
|
||||
# }
|
||||
```
|
||||
|
||||
# Install
|
||||
|
||||
```console
|
||||
$ gem install addressable
|
||||
```
|
||||
|
||||
You may optionally turn on native IDN support by installing libidn and the
|
||||
idn gem:
|
||||
|
||||
```console
|
||||
$ sudo apt-get install idn # Debian/Ubuntu
|
||||
$ brew install libidn # OS X
|
||||
$ gem install idn-ruby
|
||||
```
|
||||
|
||||
# Semantic Versioning
|
||||
|
||||
This project uses [Semantic Versioning](https://semver.org/). You can (and should) specify your
|
||||
dependency using a pessimistic version constraint covering the major and minor
|
||||
values:
|
||||
|
||||
```ruby
|
||||
spec.add_dependency 'addressable', '~> 2.5'
|
||||
```
|
||||
|
||||
If you need a specific bug fix, you can also specify minimum tiny versions
|
||||
without preventing updates to the latest minor release:
|
||||
|
||||
```ruby
|
||||
spec.add_dependency 'addressable', '~> 2.3', '>= 2.3.7'
|
||||
```
|
34
vendor/bundle/gems/addressable-2.7.0/Rakefile
vendored
34
vendor/bundle/gems/addressable-2.7.0/Rakefile
vendored
@ -1,34 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rubygems'
|
||||
require 'rake'
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'lib', 'addressable', 'version')
|
||||
|
||||
PKG_DISPLAY_NAME = 'Addressable'
|
||||
PKG_NAME = PKG_DISPLAY_NAME.downcase
|
||||
PKG_VERSION = Addressable::VERSION::STRING
|
||||
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
||||
|
||||
RELEASE_NAME = "REL #{PKG_VERSION}"
|
||||
|
||||
PKG_SUMMARY = "URI Implementation"
|
||||
PKG_DESCRIPTION = <<-TEXT
|
||||
Addressable is an alternative implementation to the URI implementation that is
|
||||
part of Ruby's standard library. It is flexible, offers heuristic parsing, and
|
||||
additionally provides extensive support for IRIs and URI templates.
|
||||
TEXT
|
||||
|
||||
PKG_FILES = FileList[
|
||||
"lib/**/*", "spec/**/*", "vendor/**/*", "data/**/*",
|
||||
"tasks/**/*",
|
||||
"[A-Z]*", "Rakefile"
|
||||
].exclude(/pkg/).exclude(/database\.yml/).
|
||||
exclude(/Gemfile\.lock/).exclude(/[_\.]git$/)
|
||||
|
||||
task :default => "spec"
|
||||
|
||||
WINDOWS = (RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/) rescue false
|
||||
SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
|
||||
|
||||
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
Binary file not shown.
@ -1,4 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'addressable/uri'
|
||||
require 'addressable/template'
|
@ -1,27 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
begin
|
||||
require "addressable/idna/native"
|
||||
rescue LoadError
|
||||
# libidn or the idn gem was not available, fall back on a pure-Ruby
|
||||
# implementation...
|
||||
require "addressable/idna/pure"
|
||||
end
|
@ -1,61 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
require "idn"
|
||||
|
||||
module Addressable
|
||||
module IDNA
|
||||
def self.punycode_encode(value)
|
||||
IDN::Punycode.encode(value.to_s)
|
||||
end
|
||||
|
||||
def self.punycode_decode(value)
|
||||
IDN::Punycode.decode(value.to_s)
|
||||
end
|
||||
|
||||
def self.unicode_normalize_kc(value)
|
||||
IDN::Stringprep.nfkc_normalize(value.to_s)
|
||||
end
|
||||
|
||||
def self.to_ascii(value)
|
||||
value.to_s.split('.', -1).map do |segment|
|
||||
if segment.size > 0 && segment.size < 64
|
||||
IDN::Idna.toASCII(segment, IDN::Idna::ALLOW_UNASSIGNED)
|
||||
elsif segment.size >= 64
|
||||
segment
|
||||
else
|
||||
''
|
||||
end
|
||||
end.join('.')
|
||||
end
|
||||
|
||||
def self.to_unicode(value)
|
||||
value.to_s.split('.', -1).map do |segment|
|
||||
if segment.size > 0 && segment.size < 64
|
||||
IDN::Idna.toUnicode(segment, IDN::Idna::ALLOW_UNASSIGNED)
|
||||
elsif segment.size >= 64
|
||||
segment
|
||||
else
|
||||
''
|
||||
end
|
||||
end.join('.')
|
||||
end
|
||||
end
|
||||
end
|
@ -1,676 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
module Addressable
|
||||
module IDNA
|
||||
# This module is loosely based on idn_actionmailer by Mick Staugaard,
|
||||
# the unicode library by Yoshida Masato, and the punycode implementation
|
||||
# by Kazuhiro Nishiyama. Most of the code was copied verbatim, but
|
||||
# some reformatting was done, and some translation from C was done.
|
||||
#
|
||||
# Without their code to work from as a base, we'd all still be relying
|
||||
# on the presence of libidn. Which nobody ever seems to have installed.
|
||||
#
|
||||
# Original sources:
|
||||
# http://github.com/staugaard/idn_actionmailer
|
||||
# http://www.yoshidam.net/Ruby.html#unicode
|
||||
# http://rubyforge.org/frs/?group_id=2550
|
||||
|
||||
|
||||
UNICODE_TABLE = File.expand_path(
|
||||
File.join(File.dirname(__FILE__), '../../..', 'data/unicode.data')
|
||||
)
|
||||
|
||||
ACE_PREFIX = "xn--"
|
||||
|
||||
UTF8_REGEX = /\A(?:
|
||||
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)*\z/mnx
|
||||
|
||||
UTF8_REGEX_MULTIBYTE = /(?:
|
||||
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)/mnx
|
||||
|
||||
# :startdoc:
|
||||
|
||||
# Converts from a Unicode internationalized domain name to an ASCII
|
||||
# domain name as described in RFC 3490.
|
||||
def self.to_ascii(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
input = input.dup
|
||||
if input.respond_to?(:force_encoding)
|
||||
input.force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
if input =~ UTF8_REGEX && input =~ UTF8_REGEX_MULTIBYTE
|
||||
parts = unicode_downcase(input).split('.')
|
||||
parts.map! do |part|
|
||||
if part.respond_to?(:force_encoding)
|
||||
part.force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE
|
||||
ACE_PREFIX + punycode_encode(unicode_normalize_kc(part))
|
||||
else
|
||||
part
|
||||
end
|
||||
end
|
||||
parts.join('.')
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Converts from an ASCII domain name to a Unicode internationalized
|
||||
# domain name as described in RFC 3490.
|
||||
def self.to_unicode(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
parts = input.split('.')
|
||||
parts.map! do |part|
|
||||
if part =~ /^#{ACE_PREFIX}(.+)/
|
||||
begin
|
||||
punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1])
|
||||
rescue Addressable::IDNA::PunycodeBadInput
|
||||
# toUnicode is explicitly defined as never-fails by the spec
|
||||
part
|
||||
end
|
||||
else
|
||||
part
|
||||
end
|
||||
end
|
||||
output = parts.join('.')
|
||||
if output.respond_to?(:force_encoding)
|
||||
output.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
# Unicode normalization form KC.
|
||||
def self.unicode_normalize_kc(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
unpacked = input.unpack("U*")
|
||||
unpacked =
|
||||
unicode_compose(unicode_sort_canonical(unicode_decompose(unpacked)))
|
||||
return unpacked.pack("U*")
|
||||
end
|
||||
|
||||
##
|
||||
# Unicode aware downcase method.
|
||||
#
|
||||
# @api private
|
||||
# @param [String] input
|
||||
# The input string.
|
||||
# @return [String] The downcased result.
|
||||
def self.unicode_downcase(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
unpacked = input.unpack("U*")
|
||||
unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) }
|
||||
return unpacked.pack("U*")
|
||||
end
|
||||
private_class_method :unicode_downcase
|
||||
|
||||
def self.unicode_compose(unpacked)
|
||||
unpacked_result = []
|
||||
length = unpacked.length
|
||||
|
||||
return unpacked if length == 0
|
||||
|
||||
starter = unpacked[0]
|
||||
starter_cc = lookup_unicode_combining_class(starter)
|
||||
starter_cc = 256 if starter_cc != 0
|
||||
for i in 1...length
|
||||
ch = unpacked[i]
|
||||
|
||||
if (starter_cc == 0 &&
|
||||
(composite = unicode_compose_pair(starter, ch)) != nil)
|
||||
starter = composite
|
||||
else
|
||||
unpacked_result << starter
|
||||
starter = ch
|
||||
end
|
||||
end
|
||||
unpacked_result << starter
|
||||
return unpacked_result
|
||||
end
|
||||
private_class_method :unicode_compose
|
||||
|
||||
def self.unicode_compose_pair(ch_one, ch_two)
|
||||
if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT &&
|
||||
ch_two >= HANGUL_VBASE && ch_two < HANGUL_VBASE + HANGUL_VCOUNT
|
||||
# Hangul L + V
|
||||
return HANGUL_SBASE + (
|
||||
(ch_one - HANGUL_LBASE) * HANGUL_VCOUNT + (ch_two - HANGUL_VBASE)
|
||||
) * HANGUL_TCOUNT
|
||||
elsif ch_one >= HANGUL_SBASE &&
|
||||
ch_one < HANGUL_SBASE + HANGUL_SCOUNT &&
|
||||
(ch_one - HANGUL_SBASE) % HANGUL_TCOUNT == 0 &&
|
||||
ch_two >= HANGUL_TBASE && ch_two < HANGUL_TBASE + HANGUL_TCOUNT
|
||||
# Hangul LV + T
|
||||
return ch_one + (ch_two - HANGUL_TBASE)
|
||||
end
|
||||
|
||||
p = []
|
||||
ucs4_to_utf8 = lambda do |ch|
|
||||
if ch < 128
|
||||
p << ch
|
||||
elsif ch < 2048
|
||||
p << (ch >> 6 | 192)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x10000
|
||||
p << (ch >> 12 | 224)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x200000
|
||||
p << (ch >> 18 | 240)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x4000000
|
||||
p << (ch >> 24 | 248)
|
||||
p << (ch >> 18 & 63 | 128)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x80000000
|
||||
p << (ch >> 30 | 252)
|
||||
p << (ch >> 24 & 63 | 128)
|
||||
p << (ch >> 18 & 63 | 128)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
end
|
||||
end
|
||||
|
||||
ucs4_to_utf8.call(ch_one)
|
||||
ucs4_to_utf8.call(ch_two)
|
||||
|
||||
return lookup_unicode_composition(p)
|
||||
end
|
||||
private_class_method :unicode_compose_pair
|
||||
|
||||
def self.unicode_sort_canonical(unpacked)
|
||||
unpacked = unpacked.dup
|
||||
i = 1
|
||||
length = unpacked.length
|
||||
|
||||
return unpacked if length < 2
|
||||
|
||||
while i < length
|
||||
last = unpacked[i-1]
|
||||
ch = unpacked[i]
|
||||
last_cc = lookup_unicode_combining_class(last)
|
||||
cc = lookup_unicode_combining_class(ch)
|
||||
if cc != 0 && last_cc != 0 && last_cc > cc
|
||||
unpacked[i] = last
|
||||
unpacked[i-1] = ch
|
||||
i -= 1 if i > 1
|
||||
else
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
return unpacked
|
||||
end
|
||||
private_class_method :unicode_sort_canonical
|
||||
|
||||
def self.unicode_decompose(unpacked)
|
||||
unpacked_result = []
|
||||
for cp in unpacked
|
||||
if cp >= HANGUL_SBASE && cp < HANGUL_SBASE + HANGUL_SCOUNT
|
||||
l, v, t = unicode_decompose_hangul(cp)
|
||||
unpacked_result << l
|
||||
unpacked_result << v if v
|
||||
unpacked_result << t if t
|
||||
else
|
||||
dc = lookup_unicode_compatibility(cp)
|
||||
unless dc
|
||||
unpacked_result << cp
|
||||
else
|
||||
unpacked_result.concat(unicode_decompose(dc.unpack("U*")))
|
||||
end
|
||||
end
|
||||
end
|
||||
return unpacked_result
|
||||
end
|
||||
private_class_method :unicode_decompose
|
||||
|
||||
def self.unicode_decompose_hangul(codepoint)
|
||||
sindex = codepoint - HANGUL_SBASE;
|
||||
if sindex < 0 || sindex >= HANGUL_SCOUNT
|
||||
l = codepoint
|
||||
v = t = nil
|
||||
return l, v, t
|
||||
end
|
||||
l = HANGUL_LBASE + sindex / HANGUL_NCOUNT
|
||||
v = HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
|
||||
t = HANGUL_TBASE + sindex % HANGUL_TCOUNT
|
||||
if t == HANGUL_TBASE
|
||||
t = nil
|
||||
end
|
||||
return l, v, t
|
||||
end
|
||||
private_class_method :unicode_decompose_hangul
|
||||
|
||||
def self.lookup_unicode_combining_class(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
(codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
|
||||
0)
|
||||
end
|
||||
private_class_method :lookup_unicode_combining_class
|
||||
|
||||
def self.lookup_unicode_compatibility(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil)
|
||||
end
|
||||
private_class_method :lookup_unicode_compatibility
|
||||
|
||||
def self.lookup_unicode_lowercase(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
(codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) :
|
||||
codepoint)
|
||||
end
|
||||
private_class_method :lookup_unicode_lowercase
|
||||
|
||||
def self.lookup_unicode_composition(unpacked)
|
||||
return COMPOSITION_TABLE[unpacked]
|
||||
end
|
||||
private_class_method :lookup_unicode_composition
|
||||
|
||||
HANGUL_SBASE = 0xac00
|
||||
HANGUL_LBASE = 0x1100
|
||||
HANGUL_LCOUNT = 19
|
||||
HANGUL_VBASE = 0x1161
|
||||
HANGUL_VCOUNT = 21
|
||||
HANGUL_TBASE = 0x11a7
|
||||
HANGUL_TCOUNT = 28
|
||||
HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT # 588
|
||||
HANGUL_SCOUNT = HANGUL_LCOUNT * HANGUL_NCOUNT # 11172
|
||||
|
||||
UNICODE_DATA_COMBINING_CLASS = 0
|
||||
UNICODE_DATA_EXCLUSION = 1
|
||||
UNICODE_DATA_CANONICAL = 2
|
||||
UNICODE_DATA_COMPATIBILITY = 3
|
||||
UNICODE_DATA_UPPERCASE = 4
|
||||
UNICODE_DATA_LOWERCASE = 5
|
||||
UNICODE_DATA_TITLECASE = 6
|
||||
|
||||
begin
|
||||
if defined?(FakeFS)
|
||||
fakefs_state = FakeFS.activated?
|
||||
FakeFS.deactivate!
|
||||
end
|
||||
# This is a sparse Unicode table. Codepoints without entries are
|
||||
# assumed to have the value: [0, 0, nil, nil, nil, nil, nil]
|
||||
UNICODE_DATA = File.open(UNICODE_TABLE, "rb") do |file|
|
||||
Marshal.load(file.read)
|
||||
end
|
||||
ensure
|
||||
if defined?(FakeFS)
|
||||
FakeFS.activate! if fakefs_state
|
||||
end
|
||||
end
|
||||
|
||||
COMPOSITION_TABLE = {}
|
||||
UNICODE_DATA.each do |codepoint, data|
|
||||
canonical = data[UNICODE_DATA_CANONICAL]
|
||||
exclusion = data[UNICODE_DATA_EXCLUSION]
|
||||
|
||||
if canonical && exclusion == 0
|
||||
COMPOSITION_TABLE[canonical.unpack("C*")] = codepoint
|
||||
end
|
||||
end
|
||||
|
||||
UNICODE_MAX_LENGTH = 256
|
||||
ACE_MAX_LENGTH = 256
|
||||
|
||||
PUNYCODE_BASE = 36
|
||||
PUNYCODE_TMIN = 1
|
||||
PUNYCODE_TMAX = 26
|
||||
PUNYCODE_SKEW = 38
|
||||
PUNYCODE_DAMP = 700
|
||||
PUNYCODE_INITIAL_BIAS = 72
|
||||
PUNYCODE_INITIAL_N = 0x80
|
||||
PUNYCODE_DELIMITER = 0x2D
|
||||
|
||||
PUNYCODE_MAXINT = 1 << 64
|
||||
|
||||
PUNYCODE_PRINT_ASCII =
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" +
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" +
|
||||
" !\"\#$%&'()*+,-./" +
|
||||
"0123456789:;<=>?" +
|
||||
"@ABCDEFGHIJKLMNO" +
|
||||
"PQRSTUVWXYZ[\\]^_" +
|
||||
"`abcdefghijklmno" +
|
||||
"pqrstuvwxyz{|}~\n"
|
||||
|
||||
# Input is invalid.
|
||||
class PunycodeBadInput < StandardError; end
|
||||
# Output would exceed the space provided.
|
||||
class PunycodeBigOutput < StandardError; end
|
||||
# Input needs wider integers to process.
|
||||
class PunycodeOverflow < StandardError; end
|
||||
|
||||
def self.punycode_encode(unicode)
|
||||
unicode = unicode.to_s unless unicode.is_a?(String)
|
||||
input = unicode.unpack("U*")
|
||||
output = [0] * (ACE_MAX_LENGTH + 1)
|
||||
input_length = input.size
|
||||
output_length = [ACE_MAX_LENGTH]
|
||||
|
||||
# Initialize the state
|
||||
n = PUNYCODE_INITIAL_N
|
||||
delta = out = 0
|
||||
max_out = output_length[0]
|
||||
bias = PUNYCODE_INITIAL_BIAS
|
||||
|
||||
# Handle the basic code points:
|
||||
input_length.times do |j|
|
||||
if punycode_basic?(input[j])
|
||||
if max_out - out < 2
|
||||
raise PunycodeBigOutput,
|
||||
"Output would exceed the space provided."
|
||||
end
|
||||
output[out] = input[j]
|
||||
out += 1
|
||||
end
|
||||
end
|
||||
|
||||
h = b = out
|
||||
|
||||
# h is the number of code points that have been handled, b is the
|
||||
# number of basic code points, and out is the number of characters
|
||||
# that have been output.
|
||||
|
||||
if b > 0
|
||||
output[out] = PUNYCODE_DELIMITER
|
||||
out += 1
|
||||
end
|
||||
|
||||
# Main encoding loop:
|
||||
|
||||
while h < input_length
|
||||
# All non-basic code points < n have been
|
||||
# handled already. Find the next larger one:
|
||||
|
||||
m = PUNYCODE_MAXINT
|
||||
input_length.times do |j|
|
||||
m = input[j] if (n...m) === input[j]
|
||||
end
|
||||
|
||||
# Increase delta enough to advance the decoder's
|
||||
# <n,i> state to <m,0>, but guard against overflow:
|
||||
|
||||
if m - n > (PUNYCODE_MAXINT - delta) / (h + 1)
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
delta += (m - n) * (h + 1)
|
||||
n = m
|
||||
|
||||
input_length.times do |j|
|
||||
# Punycode does not need to check whether input[j] is basic:
|
||||
if input[j] < n
|
||||
delta += 1
|
||||
if delta == 0
|
||||
raise PunycodeOverflow,
|
||||
"Input needs wider integers to process."
|
||||
end
|
||||
end
|
||||
|
||||
if input[j] == n
|
||||
# Represent delta as a generalized variable-length integer:
|
||||
|
||||
q = delta; k = PUNYCODE_BASE
|
||||
while true
|
||||
if out >= max_out
|
||||
raise PunycodeBigOutput,
|
||||
"Output would exceed the space provided."
|
||||
end
|
||||
t = (
|
||||
if k <= bias
|
||||
PUNYCODE_TMIN
|
||||
elsif k >= bias + PUNYCODE_TMAX
|
||||
PUNYCODE_TMAX
|
||||
else
|
||||
k - bias
|
||||
end
|
||||
)
|
||||
break if q < t
|
||||
output[out] =
|
||||
punycode_encode_digit(t + (q - t) % (PUNYCODE_BASE - t))
|
||||
out += 1
|
||||
q = (q - t) / (PUNYCODE_BASE - t)
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
output[out] = punycode_encode_digit(q)
|
||||
out += 1
|
||||
bias = punycode_adapt(delta, h + 1, h == b)
|
||||
delta = 0
|
||||
h += 1
|
||||
end
|
||||
end
|
||||
|
||||
delta += 1
|
||||
n += 1
|
||||
end
|
||||
|
||||
output_length[0] = out
|
||||
|
||||
outlen = out
|
||||
outlen.times do |j|
|
||||
c = output[j]
|
||||
unless c >= 0 && c <= 127
|
||||
raise StandardError, "Invalid output char."
|
||||
end
|
||||
unless PUNYCODE_PRINT_ASCII[c]
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
end
|
||||
|
||||
output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "")
|
||||
end
|
||||
private_class_method :punycode_encode
|
||||
|
||||
def self.punycode_decode(punycode)
|
||||
input = []
|
||||
output = []
|
||||
|
||||
if ACE_MAX_LENGTH * 2 < punycode.size
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
punycode.each_byte do |c|
|
||||
unless c >= 0 && c <= 127
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
input.push(c)
|
||||
end
|
||||
|
||||
input_length = input.length
|
||||
output_length = [UNICODE_MAX_LENGTH]
|
||||
|
||||
# Initialize the state
|
||||
n = PUNYCODE_INITIAL_N
|
||||
|
||||
out = i = 0
|
||||
max_out = output_length[0]
|
||||
bias = PUNYCODE_INITIAL_BIAS
|
||||
|
||||
# Handle the basic code points: Let b be the number of input code
|
||||
# points before the last delimiter, or 0 if there is none, then
|
||||
# copy the first b code points to the output.
|
||||
|
||||
b = 0
|
||||
input_length.times do |j|
|
||||
b = j if punycode_delimiter?(input[j])
|
||||
end
|
||||
if b > max_out
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
|
||||
b.times do |j|
|
||||
unless punycode_basic?(input[j])
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
output[out] = input[j]
|
||||
out+=1
|
||||
end
|
||||
|
||||
# Main decoding loop: Start just after the last delimiter if any
|
||||
# basic code points were copied; start at the beginning otherwise.
|
||||
|
||||
in_ = b > 0 ? b + 1 : 0
|
||||
while in_ < input_length
|
||||
|
||||
# in_ is the index of the next character to be consumed, and
|
||||
# out is the number of code points in the output array.
|
||||
|
||||
# Decode a generalized variable-length integer into delta,
|
||||
# which gets added to i. The overflow checking is easier
|
||||
# if we increase i as we go, then subtract off its starting
|
||||
# value at the end to obtain delta.
|
||||
|
||||
oldi = i; w = 1; k = PUNYCODE_BASE
|
||||
while true
|
||||
if in_ >= input_length
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
digit = punycode_decode_digit(input[in_])
|
||||
in_+=1
|
||||
if digit >= PUNYCODE_BASE
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
if digit > (PUNYCODE_MAXINT - i) / w
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
i += digit * w
|
||||
t = (
|
||||
if k <= bias
|
||||
PUNYCODE_TMIN
|
||||
elsif k >= bias + PUNYCODE_TMAX
|
||||
PUNYCODE_TMAX
|
||||
else
|
||||
k - bias
|
||||
end
|
||||
)
|
||||
break if digit < t
|
||||
if w > PUNYCODE_MAXINT / (PUNYCODE_BASE - t)
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
w *= PUNYCODE_BASE - t
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
bias = punycode_adapt(i - oldi, out + 1, oldi == 0)
|
||||
|
||||
# I was supposed to wrap around from out + 1 to 0,
|
||||
# incrementing n each time, so we'll fix that now:
|
||||
|
||||
if i / (out + 1) > PUNYCODE_MAXINT - n
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
n += i / (out + 1)
|
||||
i %= out + 1
|
||||
|
||||
# Insert n at position i of the output:
|
||||
|
||||
# not needed for Punycode:
|
||||
# raise PUNYCODE_INVALID_INPUT if decode_digit(n) <= base
|
||||
if out >= max_out
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
|
||||
#memmove(output + i + 1, output + i, (out - i) * sizeof *output)
|
||||
output[i + 1, out - i] = output[i, out - i]
|
||||
output[i] = n
|
||||
i += 1
|
||||
|
||||
out += 1
|
||||
end
|
||||
|
||||
output_length[0] = out
|
||||
|
||||
output.pack("U*")
|
||||
end
|
||||
private_class_method :punycode_decode
|
||||
|
||||
def self.punycode_basic?(codepoint)
|
||||
codepoint < 0x80
|
||||
end
|
||||
private_class_method :punycode_basic?
|
||||
|
||||
def self.punycode_delimiter?(codepoint)
|
||||
codepoint == PUNYCODE_DELIMITER
|
||||
end
|
||||
private_class_method :punycode_delimiter?
|
||||
|
||||
def self.punycode_encode_digit(d)
|
||||
d + 22 + 75 * ((d < 26) ? 1 : 0)
|
||||
end
|
||||
private_class_method :punycode_encode_digit
|
||||
|
||||
# Returns the numeric value of a basic codepoint
|
||||
# (for use in representing integers) in the range 0 to
|
||||
# base - 1, or PUNYCODE_BASE if codepoint does not represent a value.
|
||||
def self.punycode_decode_digit(codepoint)
|
||||
if codepoint - 48 < 10
|
||||
codepoint - 22
|
||||
elsif codepoint - 65 < 26
|
||||
codepoint - 65
|
||||
elsif codepoint - 97 < 26
|
||||
codepoint - 97
|
||||
else
|
||||
PUNYCODE_BASE
|
||||
end
|
||||
end
|
||||
private_class_method :punycode_decode_digit
|
||||
|
||||
# Bias adaptation method
|
||||
def self.punycode_adapt(delta, numpoints, firsttime)
|
||||
delta = firsttime ? delta / PUNYCODE_DAMP : delta >> 1
|
||||
# delta >> 1 is a faster way of doing delta / 2
|
||||
delta += delta / numpoints
|
||||
difference = PUNYCODE_BASE - PUNYCODE_TMIN
|
||||
|
||||
k = 0
|
||||
while delta > (difference * PUNYCODE_TMAX) / 2
|
||||
delta /= difference
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
k + (difference + 1) * delta / (delta + PUNYCODE_SKEW)
|
||||
end
|
||||
private_class_method :punycode_adapt
|
||||
end
|
||||
# :startdoc:
|
||||
end
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,32 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
# Used to prevent the class/module from being loaded more than once
|
||||
if !defined?(Addressable::VERSION)
|
||||
module Addressable
|
||||
module VERSION
|
||||
MAJOR = 2
|
||||
MINOR = 7
|
||||
TINY = 0
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
end
|
@ -1,300 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# coding: utf-8
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
# Have to use RubyGems to load the idn gem.
|
||||
require "rubygems"
|
||||
|
||||
require "addressable/idna"
|
||||
|
||||
shared_examples_for "converting from unicode to ASCII" do
|
||||
it "should convert 'www.google.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii("www.google.com")).to eq("www.google.com")
|
||||
end
|
||||
|
||||
long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
|
||||
it "should convert '#{long}' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(long)).to eq(long)
|
||||
end
|
||||
|
||||
it "should convert 'www.詹姆斯.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"www.詹姆斯.com"
|
||||
)).to eq("www.xn--8ws00zhy3a.com")
|
||||
end
|
||||
|
||||
it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
|
||||
"www.Iñtërnâtiônàlizætiøn.com"
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"www.I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4" +
|
||||
"n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n.com"
|
||||
)).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com")
|
||||
end
|
||||
|
||||
it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"www.In\xCC\x83te\xCC\x88rna\xCC\x82tio\xCC\x82n" +
|
||||
"a\xCC\x80liz\xC3\xA6ti\xC3\xB8n.com"
|
||||
)).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com")
|
||||
end
|
||||
|
||||
it "should convert " +
|
||||
"'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
|
||||
"correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
|
||||
"\201\252\343\201\214\343\201\204\343\202\217\343\201\221\343\201\256" +
|
||||
"\343\202\217\343\201\213\343\202\211\343\201\252\343\201\204\343\201" +
|
||||
"\251\343\202\201\343\201\204\343\202\223\343\202\201\343\201\204\343" +
|
||||
"\201\256\343\202\211\343\201\271\343\202\213\343\201\276\343\201\240" +
|
||||
"\343\201\252\343\201\214\343\201\217\343\201\227\343\201\252\343\201" +
|
||||
"\204\343\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
|
||||
"w3.mag.keio.ac.jp"
|
||||
)).to eq(
|
||||
"www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
|
||||
"fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
|
||||
)
|
||||
end
|
||||
|
||||
it "should convert " +
|
||||
"'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
|
||||
"correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
|
||||
"\201\252\343\201\213\343\202\231\343\201\204\343\202\217\343\201\221" +
|
||||
"\343\201\256\343\202\217\343\201\213\343\202\211\343\201\252\343\201" +
|
||||
"\204\343\201\250\343\202\231\343\202\201\343\201\204\343\202\223\343" +
|
||||
"\202\201\343\201\204\343\201\256\343\202\211\343\201\270\343\202\231" +
|
||||
"\343\202\213\343\201\276\343\201\237\343\202\231\343\201\252\343\201" +
|
||||
"\213\343\202\231\343\201\217\343\201\227\343\201\252\343\201\204\343" +
|
||||
"\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
|
||||
"w3.mag.keio.ac.jp"
|
||||
)).to eq(
|
||||
"www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
|
||||
"fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
|
||||
)
|
||||
end
|
||||
|
||||
it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"点心和烤鸭.w3.mag.keio.ac.jp"
|
||||
)).to eq("xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp")
|
||||
end
|
||||
|
||||
it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"가각갂갃간갅갆갇갈갉힢힣.com"
|
||||
)).to eq("xn--o39acdefghijk5883jma.com")
|
||||
end
|
||||
|
||||
it "should convert " +
|
||||
"'\347\242\274\346\250\231\346\272\226\350" +
|
||||
"\220\254\345\234\213\347\242\274.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\347\242\274\346\250\231\346\272\226\350" +
|
||||
"\220\254\345\234\213\347\242\274.com"
|
||||
)).to eq("xn--9cs565brid46mda086o.com")
|
||||
end
|
||||
|
||||
it "should convert 'リ宠퐱〹.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\357\276\230\345\256\240\355\220\261\343\200\271.com"
|
||||
)).to eq("xn--eek174hoxfpr4k.com")
|
||||
end
|
||||
|
||||
it "should convert 'リ宠퐱卄.com' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\343\203\252\345\256\240\355\220\261\345\215\204.com"
|
||||
)).to eq("xn--eek174hoxfpr4k.com")
|
||||
end
|
||||
|
||||
it "should convert 'ᆵ' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\341\206\265"
|
||||
)).to eq("xn--4ud")
|
||||
end
|
||||
|
||||
it "should convert 'ᆵ' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\357\276\257"
|
||||
)).to eq("xn--4ud")
|
||||
end
|
||||
|
||||
it "should convert '🌹🌹🌹.ws' correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"\360\237\214\271\360\237\214\271\360\237\214\271.ws"
|
||||
)).to eq("xn--2h8haa.ws")
|
||||
end
|
||||
|
||||
it "should handle two adjacent '.'s correctly" do
|
||||
expect(Addressable::IDNA.to_ascii(
|
||||
"example..host"
|
||||
)).to eq("example..host")
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for "converting from ASCII to unicode" do
|
||||
long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
|
||||
it "should convert '#{long}' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(long)).to eq(long)
|
||||
end
|
||||
|
||||
it "should return the identity conversion when punycode decode fails" do
|
||||
expect(Addressable::IDNA.to_unicode("xn--zckp1cyg1.sblo.jp")).to eq(
|
||||
"xn--zckp1cyg1.sblo.jp")
|
||||
end
|
||||
|
||||
it "should return the identity conversion when the ACE prefix has no suffix" do
|
||||
expect(Addressable::IDNA.to_unicode("xn--...-")).to eq("xn--...-")
|
||||
end
|
||||
|
||||
it "should convert 'www.google.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode("www.google.com")).to eq(
|
||||
"www.google.com")
|
||||
end
|
||||
|
||||
it "should convert 'www.詹姆斯.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"www.xn--8ws00zhy3a.com"
|
||||
)).to eq("www.詹姆斯.com")
|
||||
end
|
||||
|
||||
it "should convert '詹姆斯.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--8ws00zhy3a.com"
|
||||
)).to eq("詹姆斯.com")
|
||||
end
|
||||
|
||||
it "should convert 'www.iñtërnâtiônàlizætiøn.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
|
||||
)).to eq("www.iñtërnâtiônàlizætiøn.com")
|
||||
end
|
||||
|
||||
it "should convert 'iñtërnâtiônàlizætiøn.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--itrntinliztin-vdb0a5exd8ewcye.com"
|
||||
)).to eq("iñtërnâtiônàlizætiøn.com")
|
||||
end
|
||||
|
||||
it "should convert " +
|
||||
"'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
|
||||
"correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
|
||||
"fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
|
||||
)).to eq(
|
||||
"www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp"
|
||||
)
|
||||
end
|
||||
|
||||
it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp"
|
||||
)).to eq("点心和烤鸭.w3.mag.keio.ac.jp")
|
||||
end
|
||||
|
||||
it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--o39acdefghijk5883jma.com"
|
||||
)).to eq("가각갂갃간갅갆갇갈갉힢힣.com")
|
||||
end
|
||||
|
||||
it "should convert " +
|
||||
"'\347\242\274\346\250\231\346\272\226\350" +
|
||||
"\220\254\345\234\213\347\242\274.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--9cs565brid46mda086o.com"
|
||||
)).to eq(
|
||||
"\347\242\274\346\250\231\346\272\226\350" +
|
||||
"\220\254\345\234\213\347\242\274.com"
|
||||
)
|
||||
end
|
||||
|
||||
it "should convert 'リ宠퐱卄.com' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--eek174hoxfpr4k.com"
|
||||
)).to eq("\343\203\252\345\256\240\355\220\261\345\215\204.com")
|
||||
end
|
||||
|
||||
it "should convert 'ᆵ' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--4ud"
|
||||
)).to eq("\341\206\265")
|
||||
end
|
||||
|
||||
it "should convert '🌹🌹🌹.ws' correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"xn--2h8haa.ws"
|
||||
)).to eq("\360\237\214\271\360\237\214\271\360\237\214\271.ws")
|
||||
end
|
||||
|
||||
it "should handle two adjacent '.'s correctly" do
|
||||
expect(Addressable::IDNA.to_unicode(
|
||||
"example..host"
|
||||
)).to eq("example..host")
|
||||
end
|
||||
|
||||
it "should normalize 'string' correctly" do
|
||||
expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
|
||||
expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
|
||||
end
|
||||
end
|
||||
|
||||
describe Addressable::IDNA, "when using the pure-Ruby implementation" do
|
||||
before do
|
||||
Addressable.send(:remove_const, :IDNA)
|
||||
load "addressable/idna/pure.rb"
|
||||
end
|
||||
|
||||
it_should_behave_like "converting from unicode to ASCII"
|
||||
it_should_behave_like "converting from ASCII to unicode"
|
||||
|
||||
begin
|
||||
require "fiber"
|
||||
|
||||
it "should not blow up inside fibers" do
|
||||
f = Fiber.new do
|
||||
Addressable.send(:remove_const, :IDNA)
|
||||
load "addressable/idna/pure.rb"
|
||||
end
|
||||
f.resume
|
||||
end
|
||||
rescue LoadError
|
||||
# Fibers aren't supported in this version of Ruby, skip this test.
|
||||
warn('Fibers unsupported.')
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
require "idn"
|
||||
|
||||
describe Addressable::IDNA, "when using the native-code implementation" do
|
||||
before do
|
||||
Addressable.send(:remove_const, :IDNA)
|
||||
load "addressable/idna/native.rb"
|
||||
end
|
||||
|
||||
it_should_behave_like "converting from unicode to ASCII"
|
||||
it_should_behave_like "converting from ASCII to unicode"
|
||||
end
|
||||
rescue LoadError
|
||||
# Cannot test the native implementation without libidn support.
|
||||
warn('Could not load native IDN implementation.')
|
||||
end
|
@ -1,30 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# coding: utf-8
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
require "addressable/uri"
|
||||
require "net/http"
|
||||
|
||||
describe Net::HTTP do
|
||||
it "should be compatible with Addressable" do
|
||||
response_body =
|
||||
Net::HTTP.get(Addressable::URI.parse('http://www.google.com/'))
|
||||
expect(response_body).not_to be_nil
|
||||
end
|
||||
end
|
@ -1,106 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# coding: utf-8
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
require "addressable/uri"
|
||||
require "addressable/template"
|
||||
require "rack/mount"
|
||||
|
||||
describe Rack::Mount do
|
||||
let(:app_one) do
|
||||
proc { |env| [200, {'Content-Type' => 'text/plain'}, 'Route 1'] }
|
||||
end
|
||||
let(:app_two) do
|
||||
proc { |env| [200, {'Content-Type' => 'text/plain'}, 'Route 2'] }
|
||||
end
|
||||
let(:app_three) do
|
||||
proc { |env| [200, {'Content-Type' => 'text/plain'}, 'Route 3'] }
|
||||
end
|
||||
let(:routes) do
|
||||
s = Rack::Mount::RouteSet.new do |set|
|
||||
set.add_route(app_one, {
|
||||
:request_method => 'GET',
|
||||
:path_info => Addressable::Template.new('/one/{id}/')
|
||||
}, {:id => 'unidentified'}, :one)
|
||||
set.add_route(app_two, {
|
||||
:request_method => 'GET',
|
||||
:path_info => Addressable::Template.new('/two/')
|
||||
}, {:id => 'unidentified'}, :two)
|
||||
set.add_route(app_three, {
|
||||
:request_method => 'GET',
|
||||
:path_info => Addressable::Template.new('/three/{id}/').to_regexp
|
||||
}, {:id => 'unidentified'}, :three)
|
||||
end
|
||||
s.rehash
|
||||
s
|
||||
end
|
||||
|
||||
it "should generate from routes with Addressable::Template" do
|
||||
path, _ = routes.generate(:path_info, :one, {:id => '123'})
|
||||
expect(path).to eq '/one/123/'
|
||||
end
|
||||
|
||||
it "should generate from routes with Addressable::Template using defaults" do
|
||||
path, _ = routes.generate(:path_info, :one, {})
|
||||
expect(path).to eq '/one/unidentified/'
|
||||
end
|
||||
|
||||
it "should recognize routes with Addressable::Template" do
|
||||
request = Rack::Request.new(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'PATH_INFO' => '/one/123/'
|
||||
)
|
||||
route, _, params = routes.recognize(request)
|
||||
expect(route).not_to be_nil
|
||||
expect(route.app).to eq app_one
|
||||
expect(params).to eq({id: '123'})
|
||||
end
|
||||
|
||||
it "should generate from routes with Addressable::Template" do
|
||||
path, _ = routes.generate(:path_info, :two, {:id => '654'})
|
||||
expect(path).to eq '/two/'
|
||||
end
|
||||
|
||||
it "should generate from routes with Addressable::Template using defaults" do
|
||||
path, _ = routes.generate(:path_info, :two, {})
|
||||
expect(path).to eq '/two/'
|
||||
end
|
||||
|
||||
it "should recognize routes with Addressable::Template" do
|
||||
request = Rack::Request.new(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'PATH_INFO' => '/two/'
|
||||
)
|
||||
route, _, params = routes.recognize(request)
|
||||
expect(route).not_to be_nil
|
||||
expect(route.app).to eq app_two
|
||||
expect(params).to eq({id: 'unidentified'})
|
||||
end
|
||||
|
||||
it "should recognize routes with derived Regexp" do
|
||||
request = Rack::Request.new(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'PATH_INFO' => '/three/789/'
|
||||
)
|
||||
route, _, params = routes.recognize(request)
|
||||
expect(route).not_to be_nil
|
||||
expect(route.app).to eq app_three
|
||||
expect(params).to eq({id: '789'})
|
||||
end
|
||||
end
|
@ -1,59 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# coding: utf-8
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
require "addressable/uri"
|
||||
|
||||
describe Addressable::URI, "when created with a URI known to cause crashes " +
|
||||
"in certain browsers" do
|
||||
it "should parse correctly" do
|
||||
uri = Addressable::URI.parse('%%30%30')
|
||||
expect(uri.path).to eq('%%30%30')
|
||||
expect(uri.normalize.path).to eq('%2500')
|
||||
end
|
||||
|
||||
it "should parse correctly as a full URI" do
|
||||
uri = Addressable::URI.parse('http://www.example.com/%%30%30')
|
||||
expect(uri.path).to eq('/%%30%30')
|
||||
expect(uri.normalize.path).to eq('/%2500')
|
||||
end
|
||||
end
|
||||
|
||||
describe Addressable::URI, "when created with a URI known to cause crashes " +
|
||||
"in certain browsers" do
|
||||
it "should parse correctly" do
|
||||
uri = Addressable::URI.parse('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
|
||||
expect(uri.path).to eq('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
|
||||
expect(uri.normalize.path).to eq(
|
||||
'%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' +
|
||||
'%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' +
|
||||
'%A3%20%E0%A5%A3%20%E5%86%97'
|
||||
)
|
||||
end
|
||||
|
||||
it "should parse correctly as a full URI" do
|
||||
uri = Addressable::URI.parse('http://www.example.com/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
|
||||
expect(uri.path).to eq('/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
|
||||
expect(uri.normalize.path).to eq(
|
||||
'/%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' +
|
||||
'%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' +
|
||||
'%A3%20%E0%A5%A3%20%E5%86%97'
|
||||
)
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler/setup'
|
||||
require 'rspec/its'
|
||||
|
||||
begin
|
||||
require 'coveralls'
|
||||
Coveralls.wear! do
|
||||
add_filter "spec/"
|
||||
add_filter "vendor/"
|
||||
end
|
||||
rescue LoadError
|
||||
warn "warning: coveralls gem not found; skipping Coveralls"
|
||||
require 'simplecov'
|
||||
SimpleCov.start do
|
||||
add_filter "spec/"
|
||||
add_filter "vendor/"
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.warnings = true
|
||||
config.filter_run_when_matching :focus
|
||||
end
|
@ -1,4 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
desc "Remove all build products"
|
||||
task "clobber"
|
@ -1,93 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rubygems/package_task"
|
||||
|
||||
namespace :gem do
|
||||
GEM_SPEC = Gem::Specification.new do |s|
|
||||
s.name = PKG_NAME
|
||||
s.version = PKG_VERSION
|
||||
s.summary = PKG_SUMMARY
|
||||
s.description = PKG_DESCRIPTION
|
||||
|
||||
s.files = PKG_FILES.to_a
|
||||
|
||||
s.has_rdoc = true
|
||||
s.extra_rdoc_files = %w( README.md )
|
||||
s.rdoc_options.concat ["--main", "README.md"]
|
||||
|
||||
if !s.respond_to?(:add_development_dependency)
|
||||
puts "Cannot build Gem with this version of RubyGems."
|
||||
exit(1)
|
||||
end
|
||||
|
||||
s.required_ruby_version = ">= 2.0"
|
||||
|
||||
s.add_runtime_dependency "public_suffix", ">= 2.0.2", "< 5.0"
|
||||
s.add_development_dependency "bundler", ">= 1.0", "< 3.0"
|
||||
|
||||
s.require_path = "lib"
|
||||
|
||||
s.author = "Bob Aman"
|
||||
s.email = "bob@sporkmonger.com"
|
||||
s.homepage = "https://github.com/sporkmonger/addressable"
|
||||
s.license = "Apache-2.0"
|
||||
end
|
||||
|
||||
Gem::PackageTask.new(GEM_SPEC) do |p|
|
||||
p.gem_spec = GEM_SPEC
|
||||
p.need_tar = true
|
||||
p.need_zip = true
|
||||
end
|
||||
|
||||
desc "Generates .gemspec file"
|
||||
task :gemspec do
|
||||
spec_string = GEM_SPEC.to_ruby
|
||||
File.open("#{GEM_SPEC.name}.gemspec", "w") do |file|
|
||||
file.write spec_string
|
||||
end
|
||||
end
|
||||
|
||||
desc "Show information about the gem"
|
||||
task :debug do
|
||||
puts GEM_SPEC.to_ruby
|
||||
end
|
||||
|
||||
desc "Install the gem"
|
||||
task :install => ["clobber", "gem:package"] do
|
||||
sh "#{SUDO} gem install --local pkg/#{GEM_SPEC.full_name}"
|
||||
end
|
||||
|
||||
desc "Uninstall the gem"
|
||||
task :uninstall do
|
||||
installed_list = Gem.source_index.find_name(PKG_NAME)
|
||||
if installed_list &&
|
||||
(installed_list.collect { |s| s.version.to_s}.include?(PKG_VERSION))
|
||||
sh(
|
||||
"#{SUDO} gem uninstall --version '#{PKG_VERSION}' " +
|
||||
"--ignore-dependencies --executables #{PKG_NAME}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
desc "Reinstall the gem"
|
||||
task :reinstall => [:uninstall, :install]
|
||||
|
||||
desc "Package for release"
|
||||
task :release => ["gem:package", "gem:gemspec"] do |t|
|
||||
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
||||
abort "Versions don't match #{v} vs #{PROJ.version}" if v != PKG_VERSION
|
||||
pkg = "pkg/#{GEM_SPEC.full_name}"
|
||||
|
||||
changelog = File.open("CHANGELOG.md") { |file| file.read }
|
||||
|
||||
puts "Releasing #{PKG_NAME} v. #{PKG_VERSION}"
|
||||
Rake::Task["git:tag:create"].invoke
|
||||
end
|
||||
end
|
||||
|
||||
desc "Alias to gem:package"
|
||||
task "gem" => "gem:package"
|
||||
|
||||
task "gem:release" => "gem:gemspec"
|
||||
|
||||
task "clobber" => ["gem:clobber_package"]
|
@ -1,47 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :git do
|
||||
namespace :tag do
|
||||
desc "List tags from the Git repository"
|
||||
task :list do
|
||||
tags = `git tag -l`
|
||||
tags.gsub!("\r", "")
|
||||
tags = tags.split("\n").sort {|a, b| b <=> a }
|
||||
puts tags.join("\n")
|
||||
end
|
||||
|
||||
desc "Create a new tag in the Git repository"
|
||||
task :create do
|
||||
changelog = File.open("CHANGELOG.md", "r") { |file| file.read }
|
||||
puts "-" * 80
|
||||
puts changelog
|
||||
puts "-" * 80
|
||||
puts
|
||||
|
||||
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
||||
abort "Versions don't match #{v} vs #{PKG_VERSION}" if v != PKG_VERSION
|
||||
|
||||
git_status = `git status`
|
||||
if git_status !~ /^nothing to commit/
|
||||
abort "Working directory isn't clean."
|
||||
end
|
||||
|
||||
tag = "#{PKG_NAME}-#{PKG_VERSION}"
|
||||
msg = "Release #{PKG_NAME}-#{PKG_VERSION}"
|
||||
|
||||
existing_tags = `git tag -l #{PKG_NAME}-*`.split('\n')
|
||||
if existing_tags.include?(tag)
|
||||
warn("Tag already exists, deleting...")
|
||||
unless system "git tag -d #{tag}"
|
||||
abort "Tag deletion failed."
|
||||
end
|
||||
end
|
||||
puts "Creating git tag '#{tag}'..."
|
||||
unless system "git tag -a -m \"#{msg}\" #{tag}"
|
||||
abort "Tag creation failed."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
task "gem:release" => "git:tag:create"
|
@ -1,24 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :metrics do
|
||||
task :lines do
|
||||
lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
|
||||
for file_name in FileList["lib/**/*.rb"]
|
||||
f = File.open(file_name)
|
||||
while line = f.gets
|
||||
lines += 1
|
||||
next if line =~ /^\s*$/
|
||||
next if line =~ /^\s*#/
|
||||
codelines += 1
|
||||
end
|
||||
puts "L: #{sprintf("%4d", lines)}, " +
|
||||
"LOC #{sprintf("%4d", codelines)} | #{file_name}"
|
||||
total_lines += lines
|
||||
total_codelines += codelines
|
||||
|
||||
lines, codelines = 0, 0
|
||||
end
|
||||
|
||||
puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
|
||||
end
|
||||
end
|
@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
namespace :spec do
|
||||
RSpec::Core::RakeTask.new(:simplecov) do |t|
|
||||
t.pattern = FileList['spec/**/*_spec.rb']
|
||||
t.rspec_opts = ['--color', '--format', 'documentation']
|
||||
end
|
||||
|
||||
namespace :simplecov do
|
||||
desc "Browse the code coverage report."
|
||||
task :browse => "spec:simplecov" do
|
||||
require "launchy"
|
||||
Launchy.open("coverage/index.html")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Alias to spec:simplecov"
|
||||
task "spec" => "spec:simplecov"
|
||||
|
||||
task "clobber" => ["spec:clobber_simplecov"]
|
@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rake"
|
||||
|
||||
begin
|
||||
require "yard"
|
||||
require "yard/rake/yardoc_task"
|
||||
|
||||
namespace :doc do
|
||||
desc "Generate Yardoc documentation"
|
||||
YARD::Rake::YardocTask.new do |yardoc|
|
||||
yardoc.name = "yard"
|
||||
yardoc.options = ["--verbose", "--markup", "markdown"]
|
||||
yardoc.files = FileList[
|
||||
"lib/**/*.rb", "ext/**/*.c",
|
||||
"README.md", "CHANGELOG.md", "LICENSE.txt"
|
||||
].exclude(/idna/)
|
||||
end
|
||||
end
|
||||
|
||||
task "clobber" => ["doc:clobber_yard"]
|
||||
|
||||
desc "Alias to doc:yard"
|
||||
task "doc" => "doc:yard"
|
||||
rescue LoadError
|
||||
# If yard isn't available, it's not the end of the world
|
||||
desc "Alias to doc:rdoc"
|
||||
task "doc" => "doc:rdoc"
|
||||
end
|
11
vendor/bundle/gems/colorator-1.1.0/Gemfile
vendored
11
vendor/bundle/gems/colorator-1.1.0/Gemfile
vendored
@ -1,11 +0,0 @@
|
||||
source "https://rubygems.org"
|
||||
gemspec
|
||||
|
||||
gem "rake"
|
||||
group :development do
|
||||
gem "rspec-helpers", :require => false
|
||||
gem "luna-rspec-formatters", :require => false
|
||||
gem "pry", :require => false unless ENV[
|
||||
"CI"
|
||||
]
|
||||
end
|
@ -1,25 +0,0 @@
|
||||
## 1.1.0 / 2016-06-28
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Support jruby (#8)
|
||||
|
||||
## 1.0.0 / 2016-04-28
|
||||
|
||||
### Major enhancements
|
||||
|
||||
- Merge Simple::ANSI and Colorator. (#7)
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
- Delete unnecessary `Symbol#to_sym` (#2)
|
||||
- Change argument name of `Enumerator#each` for better code legibility (#3)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
- Convert to new RSpec expectation syntax (#1)
|
||||
- Fix `String#blue` result in README (#4)
|
||||
|
||||
## 0.1 / 2013-04-13
|
||||
|
||||
Birthday!
|
21
vendor/bundle/gems/colorator-1.1.0/LICENSE
vendored
21
vendor/bundle/gems/colorator-1.1.0/LICENSE
vendored
@ -1,21 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Parker Moore
|
||||
|
||||
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.
|
@ -1,47 +0,0 @@
|
||||
# colorator
|
||||
|
||||
Colorize your text for the terminal
|
||||
|
||||
[![Build Status](https://travis-ci.org/octopress/colorator.png?branch=master)](https://travis-ci.org/octopress/colorator)
|
||||
|
||||
## Example
|
||||
|
||||
```ruby
|
||||
"this string".red
|
||||
# => \e[31mthis string\e[0m
|
||||
"my string".blue
|
||||
# => \e[34mmy string\e[0m
|
||||
# etc...
|
||||
```
|
||||
|
||||
## Supported Colors
|
||||
|
||||
- `red`
|
||||
- `black`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `magenta`
|
||||
- `white`
|
||||
- `blue`
|
||||
- `cyan`
|
||||
- `bold`
|
||||
|
||||
## Other supported Ansi methods
|
||||
|
||||
- `clear_line`
|
||||
- `has_ansi?`, `has_color?`
|
||||
- `strip_ansi`, `strip_color`
|
||||
- `reset_ansi`, `reset_color`
|
||||
- `clear_screen`
|
||||
- `ansi_jump`
|
||||
|
||||
## Why
|
||||
|
||||
There are a bunch of gems that provide functionality like this, but none have
|
||||
as simple an API as this. Just call `"string".color` and your text will be
|
||||
colorized.
|
||||
|
||||
## License
|
||||
|
||||
MIT. Written as a single Ruby file by Brandon Mathis, converted into a gem by
|
||||
Parker Moore.
|
6
vendor/bundle/gems/colorator-1.1.0/Rakefile
vendored
6
vendor/bundle/gems/colorator-1.1.0/Rakefile
vendored
@ -1,6 +0,0 @@
|
||||
require "bundler/gem_tasks"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
task :default => :spec
|
@ -1,23 +0,0 @@
|
||||
# coding: utf-8
|
||||
|
||||
require File.expand_path('lib/colorator.rb', __dir__)
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "colorator"
|
||||
spec.summary = "Colorize your text in the terminal."
|
||||
spec.version = Colorator::VERSION
|
||||
spec.authors = ["Parker Moore", "Brandon Mathis"]
|
||||
spec.email = ["parkrmoore@gmail.com", "brandon@imathis.com"]
|
||||
spec.homepage = "https://github.com/octopress/colorator"
|
||||
spec.licenses = ["MIT"]
|
||||
|
||||
all = `git ls-files -z`.split("\x0").reject { |f| f.start_with?(".") }
|
||||
spec.files = all.select { |f| File.basename(f) == f || f =~ %r{^(bin|lib)/} }
|
||||
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.extra_rdoc_files = ["README.markdown", "LICENSE"]
|
||||
spec.rdoc_options = ["--charset=UTF-8"]
|
||||
|
||||
spec.add_development_dependency "rspec", "~> 3.1"
|
||||
end
|
111
vendor/bundle/gems/colorator-1.1.0/lib/colorator.rb
vendored
111
vendor/bundle/gems/colorator-1.1.0/lib/colorator.rb
vendored
@ -1,111 +0,0 @@
|
||||
$:.unshift File.dirname(__FILE__)
|
||||
|
||||
module Colorator
|
||||
module_function
|
||||
VERSION = "1.1.0"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
ANSI_MATCHR = /\x1b.*?[jkmsuABGKH]/
|
||||
ANSI_COLORS = {
|
||||
:black => 30,
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:yellow => 33,
|
||||
:blue => 34,
|
||||
:magenta => 35,
|
||||
:cyan => 36,
|
||||
:white => 37,
|
||||
:bold => 1
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Allows you to check if a string currently has ansi.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def has_ansi?(str)
|
||||
str.match(ANSI_MATCHR).is_a?(
|
||||
MatchData
|
||||
)
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Jump the cursor, moving it up and then back down to it's spot, allowing
|
||||
# you to do fancy things like multiple output (downloads) the way that Docker
|
||||
# does them in an async way without breaking term.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def ansi_jump(str, num)
|
||||
"\x1b[#{num}A#{clear_line(str)}\x1b[#{
|
||||
num
|
||||
}B"
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def reset_ansi(str = "")
|
||||
"\x1b[0m#{
|
||||
str
|
||||
}"
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def clear_line(str = "")
|
||||
"\x1b[2K\r#{
|
||||
str
|
||||
}"
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Strip ANSI from the current string, making it just a normal string.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def strip_ansi(str)
|
||||
str.gsub(
|
||||
ANSI_MATCHR, ""
|
||||
)
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Clear the screen's current view, so the user gets a clean output.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def clear_screen(str = "")
|
||||
"\x1b[H\x1b[2J#{
|
||||
str
|
||||
}"
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def colorize(str = "", color)
|
||||
"\x1b[#{color}m#{str}\x1b[0m"
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
Colorator::ANSI_COLORS.each do |color, code|
|
||||
define_singleton_method color do |str|
|
||||
colorize(
|
||||
str, code
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
class << self
|
||||
alias reset_color reset_ansi
|
||||
alias strip_color strip_ansi
|
||||
alias has_color? has_ansi?
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
CORE_METHODS = (
|
||||
public_methods - Object.methods
|
||||
)
|
||||
end
|
||||
|
||||
require "colorator/core_ext"
|
@ -1,9 +0,0 @@
|
||||
class String
|
||||
Colorator::CORE_METHODS.each do |method|
|
||||
define_method method do |*args|
|
||||
Colorator.public_send(method,
|
||||
self, *args
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,478 +0,0 @@
|
||||
## Current
|
||||
|
||||
## Release v1.1.5, edge v0.5.0 (10 mar 2019)
|
||||
|
||||
concurrent-ruby:
|
||||
|
||||
* fix potential leak of context on JRuby and Java 7
|
||||
|
||||
concurrent-ruby-edge:
|
||||
|
||||
* Add finalized Concurrent::Cancellation
|
||||
* Add finalized Concurrent::Throttle
|
||||
* Add finalized Concurrent::Promises::Channel
|
||||
* Add new Concurrent::ErlangActor
|
||||
|
||||
## Release v1.1.4 (14 Dec 2018)
|
||||
|
||||
* (#780) Remove java_alias of 'submit' method of Runnable to let executor service work on java 11
|
||||
* (#776) Fix NameError on defining a struct with a name which is already taken in an ancestor
|
||||
|
||||
## Release v1.1.3 (7 Nov 2018)
|
||||
|
||||
* (#775) fix partial require of the gem (although not officially supported)
|
||||
|
||||
## Release v1.1.2 (6 Nov 2018)
|
||||
|
||||
* (#773) more defensive 1.9.3 support
|
||||
|
||||
## Release v1.1.1, edge v0.4.1 (1 Nov 2018)
|
||||
|
||||
* (#768) add support for 1.9.3 back
|
||||
|
||||
## Release v1.1.0, edge v0.4.0 (31 OCt 2018) (yanked)
|
||||
|
||||
* (#768) yanked because of issues with removed 1.9.3 support
|
||||
|
||||
## Release v1.1.0.pre2, edge v0.4.0.pre2 (18 Sep 2018)
|
||||
|
||||
concurrent-ruby:
|
||||
|
||||
* fixed documentation and README links
|
||||
* fix Set for TruffleRuby and Rubinius
|
||||
* use properly supported TruffleRuby APIs
|
||||
|
||||
concurrent-ruby-edge:
|
||||
|
||||
* add Promises.zip_futures_over_on
|
||||
|
||||
## Release v1.1.0.pre1, edge v0.4.0.pre1 (15 Aug 2018)
|
||||
|
||||
concurrent-ruby:
|
||||
|
||||
* requires at least Ruby 2.0
|
||||
* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/1.1.0/Concurrent/Promises.html)
|
||||
are moved from `concurrent-ruby-edge` to `concurrent-ruby`
|
||||
* Add support for TruffleRuby
|
||||
* (#734) Fix Array/Hash/Set construction broken on TruffleRuby
|
||||
* AtomicReference fixed
|
||||
* CI stabilization
|
||||
* remove sharp dependency edge -> core
|
||||
* remove warnings
|
||||
* documentation updates
|
||||
* Exchanger is no longer documented as edge since it was already available in
|
||||
`concurrent-ruby`
|
||||
* (#644) Fix Map#each and #each_pair not returning enumerator outside of MRI
|
||||
* (#659) Edge promises fail during error handling
|
||||
* (#741) Raise on recursive Delay#value call
|
||||
* (#727) #717 fix global IO executor on JRuby
|
||||
* (#740) Drop support for CRuby 1.9, JRuby 1.7, Rubinius.
|
||||
* (#737) Move AtomicMarkableReference out of Edge
|
||||
* (#708) Prefer platform specific memory barriers
|
||||
* (#735) Fix wrong expected exception in channel spec assertion
|
||||
* (#729) Allow executor option in `Promise#then`
|
||||
* (#725) fix timeout check to use timeout_interval
|
||||
* (#719) update engine detection
|
||||
* (#660) Add specs for Promise#zip/Promise.zip ordering
|
||||
* (#654) Promise.zip execution changes
|
||||
* (#666) Add thread safe set implementation
|
||||
* (#651) #699 #to_s, #inspect should not output negative object IDs.
|
||||
* (#685) Avoid RSpec warnings about raise_error
|
||||
* (#680) Avoid RSpec monkey patching, persist spec results locally, use RSpec
|
||||
v3.7.0
|
||||
* (#665) Initialize the monitor for new subarrays on Rubinius
|
||||
* (#661) Fix error handling in edge promises
|
||||
|
||||
concurrent-ruby-edge:
|
||||
|
||||
* (#659) Edge promises fail during error handling
|
||||
* Edge files clearly separated in `lib-edge`
|
||||
* added ReInclude
|
||||
|
||||
## Release v1.0.5, edge v0.3.1 (26 Feb 2017)
|
||||
|
||||
concurrent-ruby:
|
||||
|
||||
* Documentation for Event and Semaphore
|
||||
* Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby
|
||||
* Do not depend on org.jruby.util.unsafe.UnsafeHolder
|
||||
|
||||
concurrent-ruby-edge:
|
||||
|
||||
* (#620) Actors on Pool raise an error
|
||||
* (#624) Delayed promises did not interact correctly with flatting
|
||||
* Fix arguments yielded by callback methods
|
||||
* Overridable default executor in promises factory methods
|
||||
* Asking actor to terminate will always resolve to `true`
|
||||
|
||||
## Release v1.0.4, edge v0.3.0 (27 Dec 2016)
|
||||
|
||||
concurrent-ruby:
|
||||
|
||||
* Nothing
|
||||
|
||||
concurrent-ruby-edge:
|
||||
|
||||
* New promises' API renamed, lots of improvements, edge bumped to 0.3.0
|
||||
* **Incompatible** with previous 0.2.3 version
|
||||
* see https://github.com/ruby-concurrency/concurrent-ruby/pull/522
|
||||
|
||||
## Release v1.0.3 (17 Dec 2016)
|
||||
|
||||
* Trigger execution of flattened delayed futures
|
||||
* Avoid forking for processor_count if possible
|
||||
* Semaphore Mutex and JRuby parity
|
||||
* Adds Map#each as alias to Map#each_pair
|
||||
* Fix uninitialized instance variables
|
||||
* Make Fixnum, Bignum merger ready
|
||||
* Allows Promise#then to receive an executor
|
||||
* TimerSet now survives a fork
|
||||
* Reject promise on any exception
|
||||
* Allow ThreadLocalVar to be initialized with a block
|
||||
* Support Alpha with `Concurrent::processor_count`
|
||||
* Fixes format-security error when compiling ruby_193_compatible.h
|
||||
* Concurrent::Atom#swap fixed: reraise the exceptions from block
|
||||
|
||||
## Release v1.0.2 (2 May 2016)
|
||||
|
||||
* Fix bug with `Concurrent::Map` MRI backend `#inspect` method
|
||||
* Fix bug with `Concurrent::Map` MRI backend using `Hash#value?`
|
||||
* Improved documentation and examples
|
||||
* Minor updates to Edge
|
||||
|
||||
## Release v1.0.1 (27 February 2016)
|
||||
|
||||
* Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error.
|
||||
* Better handling of `autoload` vs. `require`.
|
||||
* Improved API for Edge `Future` zipping.
|
||||
* Fix reference leak in Edge `Future` constructor .
|
||||
* Fix bug which prevented thread pools from surviving a `fork`.
|
||||
* Fix bug in which `TimerTask` did not correctly specify all its dependencies.
|
||||
* Improved support for JRuby+Truffle
|
||||
* Improved error messages.
|
||||
* Improved documentation.
|
||||
* Updated README and CONTRIBUTING.
|
||||
|
||||
## Release v1.0.0 (13 November 2015)
|
||||
|
||||
* Rename `attr_volatile_with_cas` to `attr_atomic`
|
||||
* Add `clear_each` to `LockFreeStack`
|
||||
* Update `AtomicReference` documentation
|
||||
* Further updates and improvements to the synchronization layer.
|
||||
* Performance and memory usage performance with `Actor` logging.
|
||||
* Fixed `ThreadPoolExecutor` task count methods.
|
||||
* Improved `Async` performance for both short and long-lived objects.
|
||||
* Fixed bug in `LockFreeLinkedSet`.
|
||||
* Fixed bug in which `Agent#await` triggered a validation failure.
|
||||
* Further `Channel` updates.
|
||||
* Adopted a project Code of Conduct
|
||||
* Cleared interpreter warnings
|
||||
* Fixed bug in `ThreadPoolExecutor` task count methods
|
||||
* Fixed bug in 'LockFreeLinkedSet'
|
||||
* Improved Java extension loading
|
||||
* Handle Exception children in Edge::Future
|
||||
* Continued improvements to channel
|
||||
* Removed interpreter warnings.
|
||||
* Shared constants now in `lib/concurrent/constants.rb`
|
||||
* Refactored many tests.
|
||||
* Improved synchronization layer/memory model documentation.
|
||||
* Bug fix in Edge `Future#flat`
|
||||
* Brand new `Channel` implementation in Edge gem.
|
||||
* Simplification of `RubySingleThreadExecutor`
|
||||
* `Async` improvements
|
||||
- Each object uses its own `SingleThreadExecutor` instead of the global thread pool.
|
||||
- No longers supports executor injection
|
||||
- Much better documentation
|
||||
* `Atom` updates
|
||||
- No longer `Dereferenceable`
|
||||
- Now `Observable`
|
||||
- Added a `#reset` method
|
||||
* Brand new `Agent` API and implementation. Now functionally equivalent to Clojure.
|
||||
* Continued improvements to the synchronization layer
|
||||
* Merged in the `thread_safe` gem
|
||||
- `Concurrent::Array`
|
||||
- `Concurrent::Hash`
|
||||
- `Concurrent::Map` (formerly ThreadSafe::Cache)
|
||||
- `Concurrent::Tuple`
|
||||
* Minor improvements to Concurrent::Map
|
||||
* Complete rewrite of `Exchanger`
|
||||
* Removed all deprecated code (classes, methods, constants, etc.)
|
||||
* Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object.
|
||||
* Many improved tests
|
||||
* Some internal reorganization
|
||||
|
||||
## Release v0.9.1 (09 August 2015)
|
||||
|
||||
* Fixed a Rubiniux bug in synchronization object
|
||||
* Fixed all interpreter warnings (except circular references)
|
||||
* Fixed require statements when requiring `Atom` alone
|
||||
* Significantly improved `ThreadLocalVar` on non-JRuby platforms
|
||||
* Fixed error handling in Edge `Concurrent.zip`
|
||||
* `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta
|
||||
* New `AtomicFixnum#update` method
|
||||
* Minor optimizations in `ReadWriteLock`
|
||||
* New `ReentrantReadWriteLock` class
|
||||
* `ThreadLocalVar#bind` method is now public
|
||||
* Refactored many tests
|
||||
|
||||
## Release v0.9.0 (10 July 2015)
|
||||
|
||||
* Updated `AtomicReference`
|
||||
- `AtomicReference#try_update` now simply returns instead of raising exception
|
||||
- `AtomicReference#try_update!` was added to raise exceptions if an update
|
||||
fails. Note: this is the same behavior as the old `try_update`
|
||||
* Pure Java implementations of
|
||||
- `AtomicBoolean`
|
||||
- `AtomicFixnum`
|
||||
- `Semaphore`
|
||||
* Fixed bug when pruning Ruby thread pools
|
||||
* Fixed bug in time calculations within `ScheduledTask`
|
||||
* Default `count` in `CountDownLatch` to 1
|
||||
* Use monotonic clock for all timers via `Concurrent.monotonic_time`
|
||||
- Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available
|
||||
- Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions
|
||||
- Pure Ruby implementation for everything else
|
||||
- Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask`
|
||||
* Deprecated all clock-time based timer scheduling
|
||||
- Only support scheduling by delay
|
||||
- Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask`
|
||||
* Added new `ReadWriteLock` class
|
||||
* Consistent `at_exit` behavior for Java and Ruby thread pools.
|
||||
* Added `at_exit` handler to Ruby thread pools (already in Java thread pools)
|
||||
- Ruby handler stores the object id and retrieves from `ObjectSpace`
|
||||
- JRuby disables `ObjectSpace` by default so that handler stores the object reference
|
||||
* Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler
|
||||
* Updated thread pool docs to better explain shutting down thread pools
|
||||
* Simpler `:executor` option syntax for all abstractions which support this option
|
||||
* Added `Executor#auto_terminate?` predicate method (for thread pools)
|
||||
* Added `at_exit` handler to `TimerSet`
|
||||
* Simplified auto-termination of the global executors
|
||||
- Can now disable auto-termination of global executors
|
||||
- Added shutdown/kill/wait_for_termination variants for global executors
|
||||
* Can now disable auto-termination for *all* executors (the nuclear option)
|
||||
* Simplified auto-termination of the global executors
|
||||
* Deprecated terms "task pool" and "operation pool"
|
||||
- New terms are "io executor" and "fast executor"
|
||||
- New functions added with new names
|
||||
- Deprecation warnings added to functions referencing old names
|
||||
* Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent`
|
||||
- Old functions still exist with deprecation warnings
|
||||
- New functions have updated names as appropriate
|
||||
* All high-level abstractions default to the "io executor"
|
||||
* Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load
|
||||
- This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby
|
||||
* Moved global logger up to the `Concurrent` namespace and refactored the code
|
||||
* Optimized the performance of `Delay`
|
||||
- Fixed a bug in which no executor option on construction caused block execution on a global thread pool
|
||||
* Numerous improvements and bug fixes to `TimerSet`
|
||||
* Fixed deadlock of `Future` when the handler raises Exception
|
||||
* Added shared specs for more classes
|
||||
* New concurrency abstractions including:
|
||||
- `Atom`
|
||||
- `Maybe`
|
||||
- `ImmutableStruct`
|
||||
- `MutableStruct`
|
||||
- `SettableStruct`
|
||||
* Created an Edge gem for unstable abstractions including
|
||||
- `Actor`
|
||||
- `Agent`
|
||||
- `Channel`
|
||||
- `Exchanger`
|
||||
- `LazyRegister`
|
||||
- **new Future Framework** <http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html> - unified
|
||||
implementation of Futures and Promises which combines Features of previous `Future`,
|
||||
`Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
|
||||
new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`.
|
||||
It offers better performance and does not block threads when not required.
|
||||
* Actor framework changes:
|
||||
- fixed reset loop in Pool
|
||||
- Pool can use any actor as a worker, abstract worker class is no longer needed.
|
||||
- Actor events not have format `[:event_name, *payload]` instead of just the Symbol.
|
||||
- Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability
|
||||
- Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]`
|
||||
- Linking behavior responds to :linked message by returning array of linked actors
|
||||
- Supervised behavior is removed in favour of just Linking
|
||||
- RestartingContext is supervised by default now, `supervise: true` is not required any more
|
||||
- Events can be private and public, so far only difference is that Linking will
|
||||
pass to linked actors only public messages. Adding private :restarting and
|
||||
:resetting events which are send before the actor restarts or resets allowing
|
||||
to add callbacks to cleanup current child actors.
|
||||
- Print also object_id in Reference to_s
|
||||
- Add AbstractContext#default_executor to be able to override executor class wide
|
||||
- Add basic IO example
|
||||
- Documentation somewhat improved
|
||||
- All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and
|
||||
be sure that both jobs are processed first.
|
||||
* Refactored `Channel` to use newer synchronization objects
|
||||
* Added `#reset` and `#cancel` methods to `TimerSet`
|
||||
* Added `#cancel` method to `Future` and `ScheduledTask`
|
||||
* Refactored `TimerSet` to use `ScheduledTask`
|
||||
* Updated `Async` with a factory that initializes the object
|
||||
* Deprecated `Concurrent.timer` and `Concurrent.timeout`
|
||||
* Reduced max threads on pure-Ruby thread pools (abends around 14751 threads)
|
||||
* Moved many private/internal classes/modules into "namespace" modules
|
||||
* Removed brute-force killing of threads in tests
|
||||
* Fixed a thread pool bug when the operating system cannot allocate more threads
|
||||
|
||||
## Release v0.8.0 (25 January 2015)
|
||||
|
||||
* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem.
|
||||
Please see the README for more detail.
|
||||
* Better variable isolation in `Promise` and `Future` via an `:args` option
|
||||
* Continued to update intermittently failing tests
|
||||
|
||||
## Release v0.7.2 (24 January 2015)
|
||||
|
||||
* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)
|
||||
* New `Promise.all?` and `Promise.any?` class methods
|
||||
* Renamed `:overflow_policy` on thread pools to `:fallback_policy`
|
||||
* Thread pools still accept the `:overflow_policy` option but display a warning
|
||||
* Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks)
|
||||
* Fixed minor `set_deref_options` constructor bug in `Promise` class
|
||||
* Fixed minor `require` bug in `ThreadLocalVar` class
|
||||
* Fixed race condition bug in `TimerSet` class
|
||||
* Fixed race condition bug in `TimerSet` class
|
||||
* Fixed signal bug in `TimerSet#post` method
|
||||
* Numerous non-functional updates to clear warning when running in debug mode
|
||||
* Fixed more intermittently failing tests
|
||||
* Tests now run on new Travis build environment
|
||||
* Multiple documentation updates
|
||||
|
||||
## Release v0.7.1 (4 December 2014)
|
||||
|
||||
Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release.
|
||||
|
||||
* Added `flat_map` method to `Promise`
|
||||
* Added `zip` method to `Promise`
|
||||
* Fixed bug with logging in `Actor`
|
||||
* Improvements to `Promise` tests
|
||||
* Removed actor-experimental warning
|
||||
* Added an `IndirectImmediateExecutor` class
|
||||
* Allow disabling auto termination of global executors
|
||||
* Fix thread leaking in `ThreadLocalVar` (uses `Ref` gem on non-JRuby systems)
|
||||
* Fix thread leaking when pruning pure-Ruby thread pools
|
||||
* Prevent `Actor` from using an `ImmediateExecutor` (causes deadlock)
|
||||
* Added missing synchronizations to `TimerSet`
|
||||
* Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask`
|
||||
* Fixed timing bug in `TimerTask`
|
||||
* Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero
|
||||
* Removed confusing warning when not using native extenstions
|
||||
* Improved documentation
|
||||
|
||||
## Release v0.7.0 (13 August 2014)
|
||||
|
||||
* Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem
|
||||
- Pure Ruby `MutexAtomic` atomic reference class
|
||||
- Platform native atomic reference classes `CAtomic`, `JavaAtomic`, and `RbxAtomic`
|
||||
- Automated [build process](https://github.com/ruby-concurrency/rake-compiler-dev-box)
|
||||
- Fat binary releases for [multiple platforms](https://rubygems.org/gems/concurrent-ruby/versions) including Windows (32/64), Linux (32/64), OS X (64-bit), Solaris (64-bit), and JRuby
|
||||
* C native `CAtomicBoolean`
|
||||
* C native `CAtomicFixnum`
|
||||
* Refactored intermittently failing tests
|
||||
* Added `dataflow!` and `dataflow_with!` methods to match `Future#value!` method
|
||||
* Better handling of timeout in `Agent`
|
||||
* Actor Improvements
|
||||
- Fine-grained implementation using chain of behaviors. Each behavior is responsible for single aspect like: `Termination`, `Pausing`, `Linking`, `Supervising`, etc. Users can create custom Actors easily based on their needs.
|
||||
- Supervision was added. `RestartingContext` will pause on error waiting on its supervisor to decide what to do next ( options are `:terminate!`, `:resume!`, `:reset!`, `:restart!`). Supervising behavior also supports strategies `:one_for_one` and `:one_for_all`.
|
||||
- Linking was added to be able to monitor actor's events like: `:terminated`, `:paused`, `:restarted`, etc.
|
||||
- Dead letter routing added. Rejected envelopes are collected in a configurable actor (default: `Concurrent::Actor.root.ask!(:dead_letter_routing)`)
|
||||
- Old `Actor` class removed and replaced by new implementation previously called `Actress`. `Actress` was kept as an alias for `Actor` to keep compatibility.
|
||||
- `Utils::Broadcast` actor which allows Publish–subscribe pattern.
|
||||
* More executors for managing serialized operations
|
||||
- `SerializedExecution` mixin module
|
||||
- `SerializedExecutionDelegator` for serializing *any* executor
|
||||
* Updated `Async` with serialized execution
|
||||
* Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle
|
||||
* Added a `Delay` to root `Actress` initialization
|
||||
* Minor bug fixes to thread pools
|
||||
* Refactored many intermittently failing specs
|
||||
* Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)`
|
||||
* Fixed minor bug in `RubyCachedThreadPool` overflow policy
|
||||
* Updated tests to use [RSpec 3.0](http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3)
|
||||
* Removed deprecated `Actor` class
|
||||
* Better support for Rubinius
|
||||
|
||||
## Release v0.6.1 (14 June 2014)
|
||||
|
||||
* Many improvements to `Concurrent::Actress`
|
||||
* Bug fixes to `Concurrent::RubyThreadPoolExecutor`
|
||||
* Fixed several brittle tests
|
||||
* Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html
|
||||
|
||||
## Release v0.6.0 (25 May 2014)
|
||||
|
||||
* Added `Concurrent::Observable` to encapsulate our thread safe observer sets
|
||||
* Improvements to new `Channel`
|
||||
* Major improvements to `CachedThreadPool` and `FixedThreadPool`
|
||||
* Added `SingleThreadExecutor`
|
||||
* Added `Current::timer` function
|
||||
* Added `TimerSet` executor
|
||||
* Added `AtomicBoolean`
|
||||
* `ScheduledTask` refactoring
|
||||
* Pure Ruby and JRuby-optimized `PriorityQueue` classes
|
||||
* Updated `Agent` behavior to more closely match Clojure
|
||||
* Observer sets support block callbacks to the `add_observer` method
|
||||
* New algorithm for thread creation in `RubyThreadPoolExecutor`
|
||||
* Minor API updates to `Event`
|
||||
* Rewritten `TimerTask` now an `Executor` instead of a `Runnable`
|
||||
* Fixed many brittle specs
|
||||
* Renamed `FixedThreadPool` and `CachedThreadPool` to `RubyFixedThreadPool` and `RubyCachedThreadPool`
|
||||
* Created JRuby optimized `JavaFixedThreadPool` and `JavaCachedThreadPool`
|
||||
* Consolidated fixed thread pool tests into `spec/concurrent/fixed_thread_pool_shared.rb` and `spec/concurrent/cached_thread_pool_shared.rb`
|
||||
* `FixedThreadPool` now subclasses `RubyFixedThreadPool` or `JavaFixedThreadPool` as appropriate
|
||||
* `CachedThreadPool` now subclasses `RubyCachedThreadPool` or `JavaCachedThreadPool` as appropriate
|
||||
* New `Delay` class
|
||||
* `Concurrent::processor_count` helper function
|
||||
* New `Async` module
|
||||
* Renamed `NullThreadPool` to `PerThreadExecutor`
|
||||
* Deprecated `Channel` (we are planning a new implementation based on [Go](http://golangtutorials.blogspot.com/2011/06/channels-in-go.html))
|
||||
* Added gem-level [configuration](http://robots.thoughtbot.com/mygem-configure-block)
|
||||
* Deprecated `$GLOBAL_THREAD_POOL` in lieu of gem-level configuration
|
||||
* Removed support for Ruby [1.9.2](https://www.ruby-lang.org/en/news/2013/12/17/maintenance-of-1-8-7-and-1-9-2/)
|
||||
* New `RubyThreadPoolExecutor` and `JavaThreadPoolExecutor` classes
|
||||
* All thread pools now extend the appropriate thread pool executor classes
|
||||
* All thread pools now support `:overflow_policy` (based on Java's [reject policies](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html))
|
||||
* Deprecated `UsesGlobalThreadPool` in lieu of explicit `:executor` option (dependency injection) on `Future`, `Promise`, and `Agent`
|
||||
* Added `Concurrent::dataflow_with(executor, *inputs)` method to support executor dependency injection for dataflow
|
||||
* Software transactional memory with `TVar` and `Concurrent::atomically`
|
||||
* First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel`
|
||||
* `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release.
|
||||
|
||||
## Release v0.5.0
|
||||
|
||||
This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were:
|
||||
|
||||
* Stability improvements on Ruby versions with thread-level parallelism ([JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/))
|
||||
* Creation of new low-level concurrency abstractions
|
||||
* Internal refactoring to use the new low-level abstractions
|
||||
|
||||
Most of these updates had no effect on the gem API. There are a few notable exceptions which were unavoidable. Please read the [release notes](API-Updates-in-v0.5.0) for more information.
|
||||
|
||||
Specific changes include:
|
||||
|
||||
* New class `IVar`
|
||||
* New class `MVar`
|
||||
* New class `ThreadLocalVar`
|
||||
* New class `AtomicFixnum`
|
||||
* New class method `dataflow`
|
||||
* New class `Condition`
|
||||
* New class `CountDownLatch`
|
||||
* New class `DependencyCounter`
|
||||
* New class `SafeTaskExecutor`
|
||||
* New class `CopyOnNotifyObserverSet`
|
||||
* New class `CopyOnWriteObserverSet`
|
||||
* `Future` updated with `execute` API
|
||||
* `ScheduledTask` updated with `execute` API
|
||||
* New `Promise` API
|
||||
* `Future` now extends `IVar`
|
||||
* `Postable#post?` now returns an `IVar`
|
||||
* Thread safety fixes to `Dereferenceable`
|
||||
* Thread safety fixes to `Obligation`
|
||||
* Thread safety fixes to `Supervisor`
|
||||
* Thread safety fixes to `Event`
|
||||
* Various other thread safety (race condition) fixes
|
||||
* Refactored brittle tests
|
||||
* Implemented pending tests
|
||||
* Added JRuby and Rubinius as Travis CI build targets
|
||||
* Added [CodeClimate](https://codeclimate.com/) code review
|
||||
* Improved YARD documentation
|
41
vendor/bundle/gems/concurrent-ruby-1.1.5/Gemfile
vendored
41
vendor/bundle/gems/concurrent-ruby-1.1.5/Gemfile
vendored
@ -1,41 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'lib/concurrent/version')
|
||||
require File.join(File.dirname(__FILE__ ), 'lib-edge/concurrent/edge/version')
|
||||
|
||||
no_path = ENV['NO_PATH']
|
||||
options = no_path ? {} : { path: '.' }
|
||||
|
||||
gem 'concurrent-ruby', Concurrent::VERSION, options
|
||||
gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
|
||||
gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
|
||||
|
||||
group :development do
|
||||
gem 'rake', '~> 12.0'
|
||||
gem 'rake-compiler', '~> 1.0', '>= 1.0.7'
|
||||
gem 'rake-compiler-dock', '~> 0.7.0'
|
||||
gem 'pry', '~> 0.11', platforms: :mri
|
||||
end
|
||||
|
||||
group :documentation, optional: true do
|
||||
gem 'yard', '~> 0.9.0', require: false
|
||||
gem 'redcarpet', '~> 3.0', platforms: :mri # understands github markdown
|
||||
gem 'md-ruby-eval', '~> 0.6'
|
||||
end
|
||||
|
||||
group :testing do
|
||||
gem 'rspec', '~> 3.7'
|
||||
gem 'timecop', '~> 0.7.4'
|
||||
gem 'sigdump', require: false
|
||||
end
|
||||
|
||||
# made opt-in since it will not install on jruby 1.7
|
||||
group :coverage, optional: !ENV['COVERAGE'] do
|
||||
gem 'simplecov', '~> 0.16.0', require: false
|
||||
gem 'coveralls', '~> 0.8.2', require: false
|
||||
end
|
||||
|
||||
group :benchmarks, optional: true do
|
||||
gem 'benchmark-ips', '~> 2.7'
|
||||
gem 'bench9000'
|
||||
end
|
@ -1,23 +0,0 @@
|
||||
```
|
||||
Copyright (c) Jerry D'Antonio -- released under the MIT license.
|
||||
|
||||
http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
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.
|
||||
```
|
381
vendor/bundle/gems/concurrent-ruby-1.1.5/README.md
vendored
381
vendor/bundle/gems/concurrent-ruby-1.1.5/README.md
vendored
@ -1,381 +0,0 @@
|
||||
# Concurrent Ruby
|
||||
|
||||
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby)
|
||||
[![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby)
|
||||
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
||||
[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
||||
|
||||
Modern concurrency tools for Ruby. Inspired by
|
||||
[Erlang](http://www.erlang.org/doc/reference_manual/processes.html),
|
||||
[Clojure](http://clojure.org/concurrent_programming),
|
||||
[Scala](http://akka.io/),
|
||||
[Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell),
|
||||
[F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx),
|
||||
[C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx),
|
||||
[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html),
|
||||
and classic concurrency patterns.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png" align="right" style="margin-left: 20px;" />
|
||||
|
||||
The design goals of this gem are:
|
||||
|
||||
* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better
|
||||
or why
|
||||
* Remain free of external gem dependencies
|
||||
* Stay true to the spirit of the languages providing inspiration
|
||||
* But implement in a way that makes sense for Ruby
|
||||
* Keep the semantics as idiomatic Ruby as possible
|
||||
* Support features that make sense in Ruby
|
||||
* Exclude features that don't make sense in Ruby
|
||||
* Be small, lean, and loosely coupled
|
||||
* Thread-safety
|
||||
* Backward compatibility
|
||||
|
||||
## Contributing
|
||||
|
||||
**This gem depends on
|
||||
[contributions](https://github.com/ruby-concurrency/concurrent-ruby/graphs/contributors) and we
|
||||
appreciate your help. Would you like to contribute? Great! Have a look at
|
||||
[issues with `looking-for-contributor` label](https://github.com/ruby-concurrency/concurrent-ruby/issues?q=is%3Aissue+is%3Aopen+label%3Alooking-for-contributor).** And if you pick something up let us know on the issue.
|
||||
|
||||
## Thread Safety
|
||||
|
||||
*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency
|
||||
library, providing consistent behavior and guarantees on all four of the main Ruby interpreters
|
||||
(MRI/CRuby, JRuby, Rubinius, TruffleRuby).*
|
||||
|
||||
Every abstraction in this library is thread safe. Specific thread safety guarantees are documented
|
||||
with each abstraction.
|
||||
|
||||
It is critical to remember, however, that Ruby is a language of mutable references. *No*
|
||||
concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as
|
||||
sharing a mutable object between threads and modifying it on both threads) or from creating
|
||||
deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which
|
||||
encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any
|
||||
other Ruby library, many of which support the mantra of
|
||||
["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating).
|
||||
Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and
|
||||
immutable variable types and data structures.
|
||||
|
||||
We've also initiated discussion to document [memory model](docs-source/synchronization.md) of Ruby which
|
||||
would provide consistent behaviour and guarantees on all four of the main Ruby interpreters
|
||||
(MRI/CRuby, JRuby, Rubinius, TruffleRuby).
|
||||
|
||||
## Features & Documentation
|
||||
|
||||
**The primary site for documentation is the automatically generated
|
||||
[API documentation](http://ruby-concurrency.github.io/concurrent-ruby/index.html) which is up to
|
||||
date with latest release.** This readme matches the master so may contain new stuff not yet
|
||||
released.
|
||||
|
||||
We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby).
|
||||
|
||||
### Versioning
|
||||
|
||||
* `concurrent-ruby` uses [Semantic Versioning](http://semver.org/)
|
||||
* `concurrent-ruby-ext` has always same version as `concurrent-ruby`
|
||||
* `concurrent-ruby-edge` will always be 0.y.z therefore following
|
||||
[point 4](http://semver.org/#spec-item-4) applies *"Major version zero
|
||||
(0.y.z) is for initial development. Anything may change at any time. The
|
||||
public API should not be considered stable."* However we additionally use
|
||||
following rules:
|
||||
* Minor version increment means incompatible changes were made
|
||||
* Patch version increment means only compatible changes were made
|
||||
|
||||
|
||||
#### General-purpose Concurrency Abstractions
|
||||
|
||||
* [Async](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Async.html):
|
||||
A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's
|
||||
[gen_server](http://www.erlang.org/doc/man/gen_server.html).
|
||||
* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ScheduledTask.html):
|
||||
Like a Future scheduled for a specific future time.
|
||||
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TimerTask.html):
|
||||
A Thread that periodically wakes up to perform work at regular intervals.
|
||||
* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html):
|
||||
Unified implementation of futures and promises which combines features of previous `Future`,
|
||||
`Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and (partially) `TimerTask` into a single
|
||||
framework. It extensively uses the new synchronization layer to make all the features
|
||||
**non-blocking** and **lock-free**, with the exception of obviously blocking operations like
|
||||
`#wait`, `#value`. It also offers better performance.
|
||||
|
||||
#### Thread-safe Value Objects, Structures, and Collections
|
||||
|
||||
Collection classes that were originally part of the (deprecated) `thread_safe` gem:
|
||||
|
||||
* [Array](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Array.html) A thread-safe
|
||||
subclass of Ruby's standard [Array](http://ruby-doc.org/core-2.2.0/Array.html).
|
||||
* [Hash](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Hash.html) A thread-safe
|
||||
subclass of Ruby's standard [Hash](http://ruby-doc.org/core-2.2.0/Hash.html).
|
||||
* [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe
|
||||
subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html).
|
||||
* [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object
|
||||
that should have much better performance characteristics, especially under high concurrency,
|
||||
than `Concurrent::Hash`.
|
||||
* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Tuple.html) A fixed size
|
||||
array with volatile (synchronized, thread safe) getters/setters.
|
||||
|
||||
Value objects inspired by other languages:
|
||||
|
||||
* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Maybe.html) A thread-safe,
|
||||
immutable object representing an optional value, based on
|
||||
[Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
|
||||
|
||||
Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
|
||||
|
||||
* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html)
|
||||
Immutable struct where values are set at construction and cannot be changed later.
|
||||
* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutableStruct.html)
|
||||
Synchronized, mutable struct where values can be safely changed at any time.
|
||||
* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/SettableStruct.html)
|
||||
Synchronized, write-once struct where values can be set at most once, either at construction
|
||||
or any time thereafter.
|
||||
|
||||
Thread-safe variables:
|
||||
|
||||
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Agent.html): A way to
|
||||
manage shared, mutable, *asynchronous*, independent state. Based on Clojure's
|
||||
[Agent](http://clojure.org/agents).
|
||||
* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atom.html): A way to manage
|
||||
shared, mutable, *synchronous*, independent state. Based on Clojure's
|
||||
[Atom](http://clojure.org/atoms).
|
||||
* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicBoolean.html)
|
||||
A boolean value that can be updated atomically.
|
||||
* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicFixnum.html)
|
||||
A numeric value that can be updated atomically.
|
||||
* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicReference.html)
|
||||
An object reference that may be updated atomically.
|
||||
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Exchanger.html)
|
||||
A synchronization point at which threads can pair and swap elements within pairs. Based on
|
||||
Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html).
|
||||
* [MVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MVar.html) A synchronized
|
||||
single element container. Based on Haskell's
|
||||
[MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and
|
||||
Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$).
|
||||
* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadLocalVar.html)
|
||||
A variable where the value is different for each thread.
|
||||
* [TVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TVar.html) A transactional
|
||||
variable implementing software transactional memory (STM). Based on Clojure's
|
||||
[Ref](http://clojure.org/refs).
|
||||
|
||||
#### Java-inspired ThreadPools and Other Executors
|
||||
|
||||
* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html)
|
||||
overview, which also contains a list of other Executors available.
|
||||
|
||||
#### Thread Synchronization Classes and Algorithms
|
||||
|
||||
* [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CountDownLatch.html)
|
||||
A synchronization object that allows one thread to wait on multiple other threads.
|
||||
* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CyclicBarrier.html)
|
||||
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
|
||||
* [Event](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Event.html) Old school
|
||||
kernel-style event.
|
||||
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReadWriteLock.html)
|
||||
A lock that supports multiple readers but only one writer.
|
||||
* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReentrantReadWriteLock.html)
|
||||
A read/write lock with reentrant and upgrade features.
|
||||
* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Semaphore.html)
|
||||
A counting-based locking mechanism that uses permits.
|
||||
* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicMarkableReference.html)
|
||||
|
||||
#### Deprecated
|
||||
|
||||
Deprecated features are still available and bugs are being fixed, but new features will not be added.
|
||||
|
||||
* ~~[Future](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future.html):
|
||||
An asynchronous operation that produces a value.~~ Replaced by
|
||||
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
||||
* ~~[.dataflow](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#dataflow-class_method):
|
||||
Built on Futures, Dataflow allows you to create a task that will be scheduled when all of
|
||||
its data dependencies are available.~~ Replaced by
|
||||
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
||||
* ~~[Promise](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promise.html): Similar
|
||||
to Futures, with more features.~~ Replaced by
|
||||
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
||||
* ~~[Delay](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Delay.html) Lazy evaluation
|
||||
of a block yielding an immutable result. Based on Clojure's
|
||||
[delay](https://clojuredocs.org/clojure.core/delay).~~ Replaced by
|
||||
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
||||
* ~~[IVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/IVar.html) Similar to a
|
||||
"future" but can be manually assigned once, after which it becomes immutable.~~ Replaced by
|
||||
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
||||
|
||||
### Edge Features
|
||||
|
||||
These are available in the `concurrent-ruby-edge` companion gem.
|
||||
|
||||
These features are under active development and may change frequently. They are expected not to
|
||||
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
||||
be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to
|
||||
`concurrent-ruby` when final.
|
||||
|
||||
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Actor.html): Implements
|
||||
the Actor Model, where concurrent actors exchange messages.
|
||||
*Status: Partial documentation and tests; depends on new future/promise framework; stability is good.*
|
||||
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Channel.html):
|
||||
Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)).
|
||||
Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional
|
||||
inspiration from Clojure [core.async](https://clojure.github.io/core.async/).
|
||||
*Status: Partial documentation and tests.*
|
||||
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LazyRegister.html)
|
||||
* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Edge/LockFreeLinkedSet.html)
|
||||
*Status: will be moved to core soon.*
|
||||
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LockFreeStack.html)
|
||||
*Status: missing documentation and tests.*
|
||||
* [Promises::Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises/Channel.html)
|
||||
A first in first out channel that accepts messages with push family of methods and returns
|
||||
messages with pop family of methods.
|
||||
Pop and push operations can be represented as futures, see `#pop_op` and `#push_op`.
|
||||
The capacity of the channel can be limited to support back pressure, use capacity option in `#initialize`.
|
||||
`#pop` method blocks ans `#pop_op` returns pending future if there is no message in the channel.
|
||||
If the capacity is limited the `#push` method blocks and `#push_op` returns pending future.
|
||||
* [Cancellation](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Cancellation.html)
|
||||
The Cancellation abstraction provides cooperative cancellation.
|
||||
|
||||
The standard methods `Thread#raise` of `Thread#kill` available in Ruby
|
||||
are very dangerous (see linked the blog posts bellow).
|
||||
Therefore concurrent-ruby provides an alternative.
|
||||
|
||||
* <https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/>
|
||||
* <http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/>
|
||||
* <http://blog.headius.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html>
|
||||
|
||||
It provides an object which represents a task which can be executed,
|
||||
the task has to get the reference to the object and periodically cooperatively check that it is not cancelled.
|
||||
Good practices to make tasks cancellable:
|
||||
* check cancellation every cycle of a loop which does significant work,
|
||||
* do all blocking actions in a loop with a timeout then on timeout check cancellation
|
||||
and if ok block again with the timeout
|
||||
* [Throttle](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Throttle.html)
|
||||
A tool managing concurrency level of tasks.
|
||||
* [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html)
|
||||
Actor implementation which precisely matches Erlang actor behaviour.
|
||||
Requires at least Ruby 2.1 otherwise it's not loaded.
|
||||
|
||||
## Supported Ruby versions
|
||||
|
||||
* MRI 2.0 and above
|
||||
* JRuby 9000
|
||||
* TruffleRuby are supported.
|
||||
* Any Ruby interpreter that is compliant with Ruby 2.0 or newer.
|
||||
|
||||
Actually we still support mri 1.9.3 and jruby 1.7.27 but we are looking at ways how to drop the support.
|
||||
Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.
|
||||
|
||||
The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help
|
||||
please respond to [#739](https://github.com/ruby-concurrency/concurrent-ruby/issues/739).
|
||||
|
||||
## Usage
|
||||
|
||||
Everything within this gem can be loaded simply by requiring it:
|
||||
|
||||
```ruby
|
||||
require 'concurrent'
|
||||
```
|
||||
|
||||
*Requiring only specific abstractions from Concurrent Ruby is not yet supported.*
|
||||
|
||||
To use the tools in the Edge gem it must be required separately:
|
||||
|
||||
```ruby
|
||||
require 'concurrent-edge'
|
||||
```
|
||||
|
||||
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could
|
||||
help to reveal the problem.
|
||||
|
||||
## Installation
|
||||
|
||||
```shell
|
||||
gem install concurrent-ruby
|
||||
```
|
||||
|
||||
or add the following line to Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'concurrent-ruby', require: 'concurrent'
|
||||
```
|
||||
|
||||
and run `bundle install` from your shell.
|
||||
|
||||
### Edge Gem Installation
|
||||
|
||||
The Edge gem must be installed separately from the core gem:
|
||||
|
||||
```shell
|
||||
gem install concurrent-ruby-edge
|
||||
```
|
||||
|
||||
or add the following line to Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'concurrent-ruby-edge', require: 'concurrent-edge'
|
||||
```
|
||||
|
||||
and run `bundle install` from your shell.
|
||||
|
||||
|
||||
### C Extensions for MRI
|
||||
|
||||
Potential performance improvements may be achieved under MRI by installing optional C extensions.
|
||||
To minimise installation errors the C extensions are available in the `concurrent-ruby-ext`
|
||||
extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same
|
||||
version. Simply install the extension gem too:
|
||||
|
||||
```ruby
|
||||
gem install concurrent-ruby-ext
|
||||
```
|
||||
|
||||
or add the following line to Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'concurrent-ruby-ext'
|
||||
```
|
||||
|
||||
and run `bundle install` from your shell.
|
||||
|
||||
In code it is only necessary to
|
||||
|
||||
```ruby
|
||||
require 'concurrent'
|
||||
```
|
||||
|
||||
The `concurrent-ruby` gem will automatically detect the presence of the `concurrent-ruby-ext` gem
|
||||
and load the appropriate C extensions.
|
||||
|
||||
#### Note For gem developers
|
||||
|
||||
No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The
|
||||
best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions.
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Petr Chalupa](https://github.com/pitr-ch) (lead maintainer, point-of-contact)
|
||||
* [Jerry D'Antonio](https://github.com/jdantonio) (creator)
|
||||
* [Chris Seaton](https://github.com/chrisseaton)
|
||||
|
||||
### Special Thanks to
|
||||
|
||||
* [Brian Durand](https://github.com/bdurand) for the `ref` gem
|
||||
* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
|
||||
* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
|
||||
|
||||
and to the past maintainers
|
||||
|
||||
* [Michele Della Torre](https://github.com/mighe)
|
||||
* [Paweł Obrok](https://github.com/obrok)
|
||||
* [Lucas Allan](https://github.com/lucasallan)
|
||||
|
||||
and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project
|
||||
["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018.
|
||||
|
||||
## License and Copyright
|
||||
|
||||
*Concurrent Ruby* is free software released under the
|
||||
[MIT License](http://www.opensource.org/licenses/MIT).
|
||||
|
||||
The *Concurrent Ruby* [logo](https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png) was
|
||||
designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014
|
||||
[Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved.
|
327
vendor/bundle/gems/concurrent-ruby-1.1.5/Rakefile
vendored
327
vendor/bundle/gems/concurrent-ruby-1.1.5/Rakefile
vendored
@ -1,327 +0,0 @@
|
||||
require_relative 'lib/concurrent/version'
|
||||
require_relative 'lib/concurrent/utility/engine'
|
||||
|
||||
if Concurrent.ruby_version :<, 2, 0, 0
|
||||
# @!visibility private
|
||||
module Kernel
|
||||
def __dir__
|
||||
File.dirname __FILE__
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
|
||||
ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
|
||||
edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec')
|
||||
|
||||
require 'rake/javaextensiontask'
|
||||
|
||||
Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
|
||||
ext.ext_dir = 'ext/concurrent-ruby'
|
||||
ext.lib_dir = 'lib/concurrent'
|
||||
end
|
||||
|
||||
unless Concurrent.on_jruby?
|
||||
require 'rake/extensiontask'
|
||||
|
||||
Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
|
||||
ext.ext_dir = 'ext/concurrent-ruby-ext'
|
||||
ext.lib_dir = 'lib/concurrent'
|
||||
ext.source_pattern = '*.{c,h}'
|
||||
|
||||
ext.cross_compile = true
|
||||
ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
|
||||
end
|
||||
end
|
||||
|
||||
require 'rake_compiler_dock'
|
||||
namespace :repackage do
|
||||
desc '* with Windows fat distributions'
|
||||
task :all do
|
||||
Dir.chdir(__dir__) do
|
||||
# store gems in vendor cache for docker
|
||||
sh 'bundle package'
|
||||
|
||||
# build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
|
||||
Rake::Task['lib/concurrent/concurrent_ruby.jar'].invoke
|
||||
|
||||
# build all gem files
|
||||
RakeCompilerDock.sh 'bundle install --local && bundle exec rake cross native package --trace'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'rubygems'
|
||||
require 'rubygems/package_task'
|
||||
|
||||
Gem::PackageTask.new(core_gemspec) {} if core_gemspec
|
||||
Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
|
||||
Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
|
||||
|
||||
CLEAN.include('lib/concurrent/2.*', 'lib/concurrent/*.jar')
|
||||
|
||||
begin
|
||||
require 'rspec'
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
namespace :spec do
|
||||
desc '* Configured for ci'
|
||||
RSpec::Core::RakeTask.new(:ci) do |t|
|
||||
options = %w[ --color
|
||||
--backtrace
|
||||
--order defined
|
||||
--format documentation
|
||||
--tag ~notravis ]
|
||||
t.rspec_opts = [*options].join(' ')
|
||||
end
|
||||
|
||||
desc '* test packaged and installed gems instead of local files'
|
||||
task :installed do
|
||||
Dir.chdir(__dir__) do
|
||||
sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
|
||||
sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
|
||||
sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
|
||||
ENV['NO_PATH'] = 'true'
|
||||
sh 'bundle update'
|
||||
sh 'bundle exec rake spec:ci'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc 'executed in CI'
|
||||
task :ci => [:compile, 'spec:ci']
|
||||
|
||||
task :default => [:clobber, :compile, :spec]
|
||||
rescue LoadError => e
|
||||
puts 'RSpec is not installed, skipping test task definitions: ' + e.message
|
||||
end
|
||||
|
||||
current_yard_version_name = Concurrent::VERSION
|
||||
|
||||
begin
|
||||
require 'yard'
|
||||
require 'md_ruby_eval'
|
||||
require_relative 'support/yard_full_types'
|
||||
|
||||
common_yard_options = ['--no-yardopts',
|
||||
'--no-document',
|
||||
'--no-private',
|
||||
'--embed-mixins',
|
||||
'--markup', 'markdown',
|
||||
'--title', 'Concurrent Ruby',
|
||||
'--template', 'default',
|
||||
'--template-path', 'yard-template',
|
||||
'--default-return', 'undocumented']
|
||||
|
||||
desc 'Generate YARD Documentation (signpost, master)'
|
||||
task :yard => ['yard:signpost', 'yard:master']
|
||||
|
||||
namespace :yard do
|
||||
|
||||
desc '* eval markdown files'
|
||||
task :eval_md do
|
||||
Dir.chdir File.join(__dir__, 'docs-source') do
|
||||
sh 'bundle exec md-ruby-eval --auto'
|
||||
end
|
||||
end
|
||||
|
||||
task :update_readme do
|
||||
Dir.chdir __dir__ do
|
||||
content = File.read(File.join('README.md')).
|
||||
gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
|
||||
case $1
|
||||
when 'LockFreeLinkedSet'
|
||||
"{Concurrent::Edge::#{$1} #{$1}}"
|
||||
when '.dataflow'
|
||||
'{Concurrent.dataflow Concurrent.dataflow}'
|
||||
when 'thread pool'
|
||||
'{file:thread_pools.md thread pool}'
|
||||
else
|
||||
"{Concurrent::#{$1} #{$1}}"
|
||||
end
|
||||
end
|
||||
FileUtils.mkpath 'tmp'
|
||||
File.write 'tmp/README.md', content
|
||||
end
|
||||
end
|
||||
|
||||
define_yard_task = -> name do
|
||||
output_dir = "docs/#{name}"
|
||||
|
||||
removal_name = "remove.#{name}"
|
||||
task removal_name do
|
||||
Dir.chdir __dir__ do
|
||||
FileUtils.rm_rf output_dir
|
||||
end
|
||||
end
|
||||
|
||||
desc "* of #{name} into subdir #{name}"
|
||||
YARD::Rake::YardocTask.new(name) do |yard|
|
||||
yard.options.push(
|
||||
'--output-dir', output_dir,
|
||||
'--main', 'tmp/README.md',
|
||||
*common_yard_options)
|
||||
yard.files = ['./lib/**/*.rb',
|
||||
'./lib-edge/**/*.rb',
|
||||
'./ext/concurrent_ruby_ext/**/*.c',
|
||||
'-',
|
||||
'docs-source/thread_pools.md',
|
||||
'docs-source/promises.out.md',
|
||||
'docs-source/medium-example.out.rb',
|
||||
'LICENSE.md',
|
||||
'CHANGELOG.md']
|
||||
end
|
||||
Rake::Task[name].prerequisites.push removal_name, 'yard:eval_md', 'yard:update_readme'
|
||||
end
|
||||
|
||||
define_yard_task.call current_yard_version_name
|
||||
define_yard_task.call 'master'
|
||||
|
||||
desc "* signpost for versions"
|
||||
YARD::Rake::YardocTask.new(:signpost) do |yard|
|
||||
yard.options.push(
|
||||
'--output-dir', 'docs',
|
||||
'--main', 'docs-source/signpost.md',
|
||||
*common_yard_options)
|
||||
yard.files = ['no-lib']
|
||||
end
|
||||
|
||||
define_uptodate_task = -> name do
|
||||
namespace name do
|
||||
desc "** ensure that #{name} generated documentation is matching the source code"
|
||||
task :uptodate do
|
||||
Dir.chdir(__dir__) do
|
||||
begin
|
||||
FileUtils.cp_r 'docs', 'docs-copy', verbose: true
|
||||
Rake::Task["yard:#{name}"].invoke
|
||||
sh 'diff -r docs/ docs-copy/' do |ok, res|
|
||||
unless ok
|
||||
begin
|
||||
STDOUT.puts 'Command failed. Continue? (y/n)'
|
||||
input = STDIN.gets.strip.downcase
|
||||
end until %w(y n).include?(input)
|
||||
exit 1 if input == 'n'
|
||||
end
|
||||
end
|
||||
ensure
|
||||
FileUtils.rm_rf 'docs-copy', verbose: true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
define_uptodate_task.call current_yard_version_name
|
||||
define_uptodate_task.call 'master'
|
||||
end
|
||||
|
||||
rescue LoadError => e
|
||||
puts 'YARD is not installed, skipping documentation task definitions: ' + e.message
|
||||
end
|
||||
|
||||
desc 'build, test, and publish the gem'
|
||||
task :release => ['release:checks', 'release:build', 'release:test', 'release:publish']
|
||||
|
||||
namespace :release do
|
||||
# Depends on environment of @pitr-ch
|
||||
|
||||
mri_version = '2.5.1'
|
||||
jruby_version = 'jruby-9.1.17.1'
|
||||
|
||||
task :checks => "yard:#{current_yard_version_name}:uptodate" do
|
||||
Dir.chdir(__dir__) do
|
||||
sh 'test -z "$(git status --porcelain)"' do |ok, res|
|
||||
unless ok
|
||||
begin
|
||||
STDOUT.puts 'Command failed. Continue? (y/n)'
|
||||
input = STDIN.gets.strip.downcase
|
||||
end until %w(y n).include?(input)
|
||||
exit 1 if input == 'n'
|
||||
end
|
||||
end
|
||||
sh 'git fetch'
|
||||
sh 'test $(git show-ref --verify --hash refs/heads/master) = ' +
|
||||
'$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
|
||||
unless ok
|
||||
begin
|
||||
STDOUT.puts 'Command failed. Continue? (y/n)'
|
||||
input = STDIN.gets.strip.downcase
|
||||
end until %w(y n).include?(input)
|
||||
exit 1 if input == 'n'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc '* build all *.gem files necessary for release'
|
||||
task :build => [:clobber, 'repackage:all']
|
||||
|
||||
desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
|
||||
task :test do
|
||||
Dir.chdir(__dir__) do
|
||||
old = ENV['RBENV_VERSION']
|
||||
|
||||
ENV['RBENV_VERSION'] = mri_version
|
||||
sh 'rbenv version'
|
||||
sh 'bundle exec rake spec:installed'
|
||||
|
||||
ENV['RBENV_VERSION'] = jruby_version
|
||||
sh 'rbenv version'
|
||||
sh 'bundle exec rake spec:installed'
|
||||
|
||||
puts 'Windows build is untested'
|
||||
|
||||
ENV['RBENV_VERSION'] = old
|
||||
end
|
||||
end
|
||||
|
||||
desc '* do all nested steps'
|
||||
task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
|
||||
|
||||
namespace :publish do
|
||||
publish_edge = false
|
||||
|
||||
task :ask do
|
||||
begin
|
||||
STDOUT.puts 'Do you want to publish anything? (y/n)'
|
||||
input = STDIN.gets.strip.downcase
|
||||
end until %w(y n).include?(input)
|
||||
exit 1 if input == 'n'
|
||||
begin
|
||||
STDOUT.puts 'Do you want to publish edge? (y/n)'
|
||||
input = STDIN.gets.strip.downcase
|
||||
end until %w(y n).include?(input)
|
||||
publish_edge = input == 'y'
|
||||
end
|
||||
|
||||
desc '** tag HEAD with current version and push to github'
|
||||
task :tag do
|
||||
Dir.chdir(__dir__) do
|
||||
sh "git tag v#{Concurrent::VERSION}"
|
||||
sh "git push origin v#{Concurrent::VERSION}"
|
||||
sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
||||
sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
||||
end
|
||||
end
|
||||
|
||||
desc '** push all *.gem files to rubygems'
|
||||
task :rubygems do
|
||||
Dir.chdir(__dir__) do
|
||||
sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
|
||||
sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
|
||||
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem"
|
||||
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem"
|
||||
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem"
|
||||
end
|
||||
end
|
||||
|
||||
desc '** print post release steps'
|
||||
task :post_steps do
|
||||
puts 'Manually: create a release on GitHub with relevant changelog part'
|
||||
puts 'Manually: send email same as release with relevant changelog part'
|
||||
puts 'Manually: tweet'
|
||||
end
|
||||
end
|
||||
end
|
@ -1,17 +0,0 @@
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.runtime.load.BasicLibraryService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ConcurrentRubyService implements BasicLibraryService {
|
||||
|
||||
public boolean basicLoad(final Ruby runtime) throws IOException {
|
||||
new com.concurrent_ruby.ext.AtomicReferenceLibrary().load(runtime, false);
|
||||
new com.concurrent_ruby.ext.JavaAtomicBooleanLibrary().load(runtime, false);
|
||||
new com.concurrent_ruby.ext.JavaAtomicFixnumLibrary().load(runtime, false);
|
||||
new com.concurrent_ruby.ext.JavaSemaphoreLibrary().load(runtime, false);
|
||||
new com.concurrent_ruby.ext.SynchronizationLibrary().load(runtime, false);
|
||||
new com.concurrent_ruby.ext.JRubyMapBackendLibrary().load(runtime, false);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.RubyNumeric;
|
||||
import org.jruby.RubyObject;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.Library;
|
||||
|
||||
/**
|
||||
* This library adds an atomic reference type to JRuby for use in the atomic
|
||||
* library. We do a native version to avoid the implicit value coercion that
|
||||
* normally happens through JI.
|
||||
*
|
||||
* @author headius
|
||||
*/
|
||||
public class AtomicReferenceLibrary implements Library {
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
RubyModule concurrentMod = runtime.defineModule("Concurrent");
|
||||
RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
|
||||
try {
|
||||
sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class);
|
||||
atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR);
|
||||
} catch (Exception e) {
|
||||
// leave it as Java 6/7 version
|
||||
}
|
||||
atomicCls.defineAnnotatedMethods(JRubyReference.class);
|
||||
}
|
||||
|
||||
private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRubyReference(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRubyReference8(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
@JRubyClass(name="JRubyReference", parent="Object")
|
||||
public static class JRubyReference extends RubyObject {
|
||||
volatile IRubyObject reference;
|
||||
|
||||
static final sun.misc.Unsafe UNSAFE;
|
||||
static final long referenceOffset;
|
||||
|
||||
static {
|
||||
try {
|
||||
UNSAFE = UnsafeHolder.U;
|
||||
Class k = JRubyReference.class;
|
||||
referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public JRubyReference(Ruby runtime, RubyClass klass) {
|
||||
super(runtime, klass);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context) {
|
||||
UNSAFE.putObject(this, referenceOffset, context.nil);
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context, IRubyObject value) {
|
||||
UNSAFE.putObject(this, referenceOffset, value);
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"get", "value"})
|
||||
public IRubyObject get() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"set", "value="})
|
||||
public IRubyObject set(IRubyObject newValue) {
|
||||
UNSAFE.putObjectVolatile(this, referenceOffset, newValue);
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
|
||||
public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
|
||||
Ruby runtime = context.runtime;
|
||||
|
||||
if (expectedValue instanceof RubyNumeric) {
|
||||
// numerics are not always idempotent in Ruby, so we need to do slower logic
|
||||
return compareAndSetNumeric(context, expectedValue, newValue);
|
||||
}
|
||||
|
||||
return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"get_and_set", "swap"})
|
||||
public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
|
||||
// less-efficient version for Java 6 and 7
|
||||
while (true) {
|
||||
IRubyObject oldValue = get();
|
||||
if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) {
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
|
||||
Ruby runtime = context.runtime;
|
||||
|
||||
// loop until:
|
||||
// * reference CAS would succeed for same-valued objects
|
||||
// * current and expected have different values as determined by #equals
|
||||
while (true) {
|
||||
IRubyObject current = reference;
|
||||
|
||||
if (!(current instanceof RubyNumeric)) {
|
||||
// old value is not numeric, CAS fails
|
||||
return runtime.getFalse();
|
||||
}
|
||||
|
||||
RubyNumeric currentNumber = (RubyNumeric)current;
|
||||
if (!currentNumber.equals(expectedValue)) {
|
||||
// current number does not equal expected, fail CAS
|
||||
return runtime.getFalse();
|
||||
}
|
||||
|
||||
// check that current has not changed, or else allow loop to repeat
|
||||
boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
|
||||
if (success) {
|
||||
// value is same and did not change in interim...success
|
||||
return runtime.getTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UnsafeHolder {
|
||||
private UnsafeHolder(){}
|
||||
|
||||
public static final sun.misc.Unsafe U = loadUnsafe();
|
||||
|
||||
private static sun.misc.Unsafe loadUnsafe() {
|
||||
try {
|
||||
Class unsafeClass = Class.forName("sun.misc.Unsafe");
|
||||
Field f = unsafeClass.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
return (sun.misc.Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class JRubyReference8 extends JRubyReference {
|
||||
public JRubyReference8(Ruby runtime, RubyClass klass) {
|
||||
super(runtime, klass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
|
||||
// efficient version for Java 8
|
||||
return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import org.jruby.*;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap;
|
||||
import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8;
|
||||
import com.concurrent_ruby.ext.jsr166e.nounsafe.*;
|
||||
import org.jruby.runtime.Block;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.Library;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jruby.runtime.Visibility.PRIVATE;
|
||||
|
||||
/**
|
||||
* Native Java implementation to avoid the JI overhead.
|
||||
*
|
||||
* @author thedarkone
|
||||
*/
|
||||
public class JRubyMapBackendLibrary implements Library {
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
|
||||
RubyModule concurrentMod = runtime.defineModule("Concurrent");
|
||||
RubyModule thread_safeMod = concurrentMod.defineModuleUnder("Collection");
|
||||
RubyClass jrubyRefClass = thread_safeMod.defineClassUnder("JRubyMapBackend", runtime.getObject(), BACKEND_ALLOCATOR);
|
||||
jrubyRefClass.setAllocator(BACKEND_ALLOCATOR);
|
||||
jrubyRefClass.defineAnnotatedMethods(JRubyMapBackend.class);
|
||||
}
|
||||
|
||||
private static final ObjectAllocator BACKEND_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRubyMapBackend(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
@JRubyClass(name="JRubyMapBackend", parent="Object")
|
||||
public static class JRubyMapBackend extends RubyObject {
|
||||
// Defaults used by the CHM
|
||||
static final int DEFAULT_INITIAL_CAPACITY = 16;
|
||||
static final float DEFAULT_LOAD_FACTOR = 0.75f;
|
||||
|
||||
public static final boolean CAN_USE_UNSAFE_CHM = canUseUnsafeCHM();
|
||||
|
||||
private ConcurrentHashMap<IRubyObject, IRubyObject> map;
|
||||
|
||||
private static ConcurrentHashMap<IRubyObject, IRubyObject> newCHM(int initialCapacity, float loadFactor) {
|
||||
if (CAN_USE_UNSAFE_CHM) {
|
||||
return new ConcurrentHashMapV8<IRubyObject, IRubyObject>(initialCapacity, loadFactor);
|
||||
} else {
|
||||
return new com.concurrent_ruby.ext.jsr166e.nounsafe.ConcurrentHashMapV8<IRubyObject, IRubyObject>(initialCapacity, loadFactor);
|
||||
}
|
||||
}
|
||||
|
||||
private static ConcurrentHashMap<IRubyObject, IRubyObject> newCHM() {
|
||||
return newCHM(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
private static boolean canUseUnsafeCHM() {
|
||||
try {
|
||||
new com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8(); // force class load and initialization
|
||||
return true;
|
||||
} catch (Throwable t) { // ensuring we really do catch everything
|
||||
// Doug's Unsafe setup errors always have this "Could not ini.." message
|
||||
if (isCausedBySecurityException(t)) {
|
||||
return false;
|
||||
}
|
||||
throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCausedBySecurityException(Throwable t) {
|
||||
while (t != null) {
|
||||
if ((t.getMessage() != null && t.getMessage().contains("Could not initialize intrinsics")) || t instanceof SecurityException) {
|
||||
return true;
|
||||
}
|
||||
t = t.getCause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public JRubyMapBackend(Ruby runtime, RubyClass klass) {
|
||||
super(runtime, klass);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context) {
|
||||
map = newCHM();
|
||||
return context.getRuntime().getNil();
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context, IRubyObject options) {
|
||||
map = toCHM(context, options);
|
||||
return context.getRuntime().getNil();
|
||||
}
|
||||
|
||||
private ConcurrentHashMap<IRubyObject, IRubyObject> toCHM(ThreadContext context, IRubyObject options) {
|
||||
Ruby runtime = context.getRuntime();
|
||||
if (!options.isNil() && options.respondsTo("[]")) {
|
||||
IRubyObject rInitialCapacity = options.callMethod(context, "[]", runtime.newSymbol("initial_capacity"));
|
||||
IRubyObject rLoadFactor = options.callMethod(context, "[]", runtime.newSymbol("load_factor"));
|
||||
int initialCapacity = !rInitialCapacity.isNil() ? RubyNumeric.num2int(rInitialCapacity.convertToInteger()) : DEFAULT_INITIAL_CAPACITY;
|
||||
float loadFactor = !rLoadFactor.isNil() ? (float)RubyNumeric.num2dbl(rLoadFactor.convertToFloat()) : DEFAULT_LOAD_FACTOR;
|
||||
return newCHM(initialCapacity, loadFactor);
|
||||
} else {
|
||||
return newCHM();
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "[]", required = 1)
|
||||
public IRubyObject op_aref(ThreadContext context, IRubyObject key) {
|
||||
IRubyObject value;
|
||||
return ((value = map.get(key)) == null) ? context.getRuntime().getNil() : value;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"[]="}, required = 2)
|
||||
public IRubyObject op_aset(IRubyObject key, IRubyObject value) {
|
||||
map.put(key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject put_if_absent(IRubyObject key, IRubyObject value) {
|
||||
IRubyObject result = map.putIfAbsent(key, value);
|
||||
return result == null ? getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject compute_if_absent(final ThreadContext context, final IRubyObject key, final Block block) {
|
||||
return map.computeIfAbsent(key, new ConcurrentHashMap.Fun<IRubyObject, IRubyObject>() {
|
||||
@Override
|
||||
public IRubyObject apply(IRubyObject key) {
|
||||
return block.yieldSpecific(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject compute_if_present(final ThreadContext context, final IRubyObject key, final Block block) {
|
||||
IRubyObject result = map.computeIfPresent(key, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
|
||||
@Override
|
||||
public IRubyObject apply(IRubyObject key, IRubyObject oldValue) {
|
||||
IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
|
||||
return result.isNil() ? null : result;
|
||||
}
|
||||
});
|
||||
return result == null ? context.getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject compute(final ThreadContext context, final IRubyObject key, final Block block) {
|
||||
IRubyObject result = map.compute(key, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
|
||||
@Override
|
||||
public IRubyObject apply(IRubyObject key, IRubyObject oldValue) {
|
||||
IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
|
||||
return result.isNil() ? null : result;
|
||||
}
|
||||
});
|
||||
return result == null ? context.getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject merge_pair(final ThreadContext context, final IRubyObject key, final IRubyObject value, final Block block) {
|
||||
IRubyObject result = map.merge(key, value, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
|
||||
@Override
|
||||
public IRubyObject apply(IRubyObject oldValue, IRubyObject newValue) {
|
||||
IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
|
||||
return result.isNil() ? null : result;
|
||||
}
|
||||
});
|
||||
return result == null ? context.getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public RubyBoolean replace_pair(IRubyObject key, IRubyObject oldValue, IRubyObject newValue) {
|
||||
return getRuntime().newBoolean(map.replace(key, oldValue, newValue));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "key?", required = 1)
|
||||
public RubyBoolean has_key_p(IRubyObject key) {
|
||||
return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse();
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject key(IRubyObject value) {
|
||||
final IRubyObject key = map.findKey(value);
|
||||
return key == null ? getRuntime().getNil() : key;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) {
|
||||
IRubyObject result = map.replace(key, value);
|
||||
return result == null ? getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject get_and_set(IRubyObject key, IRubyObject value) {
|
||||
IRubyObject result = map.put(key, value);
|
||||
return result == null ? getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject delete(IRubyObject key) {
|
||||
IRubyObject result = map.remove(key);
|
||||
return result == null ? getRuntime().getNil() : result;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public RubyBoolean delete_pair(IRubyObject key, IRubyObject value) {
|
||||
return getRuntime().newBoolean(map.remove(key, value));
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject clear() {
|
||||
map.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject each_pair(ThreadContext context, Block block) {
|
||||
for (Map.Entry<IRubyObject,IRubyObject> entry : map.entrySet()) {
|
||||
block.yieldSpecific(context, entry.getKey(), entry.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public RubyFixnum size(ThreadContext context) {
|
||||
return context.getRuntime().newFixnum(map.size());
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject get_or_default(IRubyObject key, IRubyObject defaultValue) {
|
||||
return map.getValueOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@JRubyMethod(visibility = PRIVATE)
|
||||
public JRubyMapBackend initialize_copy(ThreadContext context, IRubyObject other) {
|
||||
map = newCHM();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyBoolean;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.RubyNil;
|
||||
import org.jruby.RubyObject;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.Library;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class JavaAtomicBooleanLibrary implements Library {
|
||||
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
RubyModule concurrentMod = runtime.defineModule("Concurrent");
|
||||
RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicBoolean", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
|
||||
atomicCls.defineAnnotatedMethods(JavaAtomicBoolean.class);
|
||||
}
|
||||
|
||||
private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JavaAtomicBoolean(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
@JRubyClass(name = "JavaAtomicBoolean", parent = "Object")
|
||||
public static class JavaAtomicBoolean extends RubyObject {
|
||||
|
||||
private AtomicBoolean atomicBoolean;
|
||||
|
||||
public JavaAtomicBoolean(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context, IRubyObject value) {
|
||||
atomicBoolean = new AtomicBoolean(convertRubyBooleanToJavaBoolean(value));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context) {
|
||||
atomicBoolean = new AtomicBoolean();
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "value")
|
||||
public IRubyObject value() {
|
||||
return getRuntime().newBoolean(atomicBoolean.get());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "true?")
|
||||
public IRubyObject isAtomicTrue() {
|
||||
return getRuntime().newBoolean(atomicBoolean.get());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "false?")
|
||||
public IRubyObject isAtomicFalse() {
|
||||
return getRuntime().newBoolean((atomicBoolean.get() == false));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "value=")
|
||||
public IRubyObject setAtomic(ThreadContext context, IRubyObject newValue) {
|
||||
atomicBoolean.set(convertRubyBooleanToJavaBoolean(newValue));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "make_true")
|
||||
public IRubyObject makeTrue() {
|
||||
return getRuntime().newBoolean(atomicBoolean.compareAndSet(false, true));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "make_false")
|
||||
public IRubyObject makeFalse() {
|
||||
return getRuntime().newBoolean(atomicBoolean.compareAndSet(true, false));
|
||||
}
|
||||
|
||||
private boolean convertRubyBooleanToJavaBoolean(IRubyObject newValue) {
|
||||
if (newValue instanceof RubyBoolean.False || newValue instanceof RubyNil) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyFixnum;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.RubyObject;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.Library;
|
||||
import org.jruby.runtime.Block;
|
||||
|
||||
public class JavaAtomicFixnumLibrary implements Library {
|
||||
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
RubyModule concurrentMod = runtime.defineModule("Concurrent");
|
||||
RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicFixnum", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
|
||||
|
||||
atomicCls.defineAnnotatedMethods(JavaAtomicFixnum.class);
|
||||
}
|
||||
|
||||
private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JavaAtomicFixnum(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
@JRubyClass(name = "JavaAtomicFixnum", parent = "Object")
|
||||
public static class JavaAtomicFixnum extends RubyObject {
|
||||
|
||||
private AtomicLong atomicLong;
|
||||
|
||||
public JavaAtomicFixnum(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context) {
|
||||
this.atomicLong = new AtomicLong(0);
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context, IRubyObject value) {
|
||||
this.atomicLong = new AtomicLong(rubyFixnumToLong(value));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "value")
|
||||
public IRubyObject getValue() {
|
||||
return getRuntime().newFixnum(atomicLong.get());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "value=")
|
||||
public IRubyObject setValue(ThreadContext context, IRubyObject newValue) {
|
||||
atomicLong.set(rubyFixnumToLong(newValue));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"increment", "up"})
|
||||
public IRubyObject increment() {
|
||||
return getRuntime().newFixnum(atomicLong.incrementAndGet());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"increment", "up"})
|
||||
public IRubyObject increment(IRubyObject value) {
|
||||
long delta = rubyFixnumToLong(value);
|
||||
return getRuntime().newFixnum(atomicLong.addAndGet(delta));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"decrement", "down"})
|
||||
public IRubyObject decrement() {
|
||||
return getRuntime().newFixnum(atomicLong.decrementAndGet());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"decrement", "down"})
|
||||
public IRubyObject decrement(IRubyObject value) {
|
||||
long delta = rubyFixnumToLong(value);
|
||||
return getRuntime().newFixnum(atomicLong.addAndGet(-delta));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "compare_and_set")
|
||||
public IRubyObject compareAndSet(ThreadContext context, IRubyObject expect, IRubyObject update) {
|
||||
return getRuntime().newBoolean(atomicLong.compareAndSet(rubyFixnumToLong(expect), rubyFixnumToLong(update)));
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject update(ThreadContext context, Block block) {
|
||||
for (;;) {
|
||||
long _oldValue = atomicLong.get();
|
||||
IRubyObject oldValue = getRuntime().newFixnum(_oldValue);
|
||||
IRubyObject newValue = block.yield(context, oldValue);
|
||||
if (atomicLong.compareAndSet(_oldValue, rubyFixnumToLong(newValue))) {
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long rubyFixnumToLong(IRubyObject value) {
|
||||
if (value instanceof RubyFixnum) {
|
||||
RubyFixnum fixNum = (RubyFixnum) value;
|
||||
return fixNum.getLongValue();
|
||||
} else {
|
||||
throw getRuntime().newArgumentError("value must be a Fixnum");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyFixnum;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.RubyNumeric;
|
||||
import org.jruby.RubyObject;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
|
||||
public class JavaSemaphoreLibrary {
|
||||
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
RubyModule concurrentMod = runtime.defineModule("Concurrent");
|
||||
RubyClass atomicCls = concurrentMod.defineClassUnder("JavaSemaphore", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
|
||||
|
||||
atomicCls.defineAnnotatedMethods(JavaSemaphore.class);
|
||||
}
|
||||
|
||||
private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JavaSemaphore(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
@JRubyClass(name = "JavaSemaphore", parent = "Object")
|
||||
public static class JavaSemaphore extends RubyObject {
|
||||
|
||||
private JRubySemaphore semaphore;
|
||||
|
||||
public JavaSemaphore(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject initialize(ThreadContext context, IRubyObject value) {
|
||||
this.semaphore = new JRubySemaphore(rubyFixnumInt(value, "count"));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject acquire(ThreadContext context, IRubyObject value) throws InterruptedException {
|
||||
this.semaphore.acquire(rubyFixnumToPositiveInt(value, "permits"));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "available_permits")
|
||||
public IRubyObject availablePermits(ThreadContext context) {
|
||||
return getRuntime().newFixnum(this.semaphore.availablePermits());
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "drain_permits")
|
||||
public IRubyObject drainPermits(ThreadContext context) {
|
||||
return getRuntime().newFixnum(this.semaphore.drainPermits());
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject acquire(ThreadContext context) throws InterruptedException {
|
||||
this.semaphore.acquire(1);
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "try_acquire")
|
||||
public IRubyObject tryAcquire(ThreadContext context) throws InterruptedException {
|
||||
return getRuntime().newBoolean(semaphore.tryAcquire(1));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "try_acquire")
|
||||
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits) throws InterruptedException {
|
||||
return getRuntime().newBoolean(semaphore.tryAcquire(rubyFixnumToPositiveInt(permits, "permits")));
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "try_acquire")
|
||||
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout) throws InterruptedException {
|
||||
return getRuntime().newBoolean(
|
||||
semaphore.tryAcquire(
|
||||
rubyFixnumToPositiveInt(permits, "permits"),
|
||||
rubyNumericToLong(timeout, "timeout"),
|
||||
java.util.concurrent.TimeUnit.SECONDS)
|
||||
);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject release(ThreadContext context) {
|
||||
this.semaphore.release(1);
|
||||
return getRuntime().newBoolean(true);
|
||||
}
|
||||
|
||||
@JRubyMethod
|
||||
public IRubyObject release(ThreadContext context, IRubyObject value) {
|
||||
this.semaphore.release(rubyFixnumToPositiveInt(value, "permits"));
|
||||
return getRuntime().newBoolean(true);
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "reduce_permits")
|
||||
public IRubyObject reducePermits(ThreadContext context, IRubyObject reduction) throws InterruptedException {
|
||||
this.semaphore.publicReducePermits(rubyFixnumToNonNegativeInt(reduction, "reduction"));
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
private int rubyFixnumInt(IRubyObject value, String paramName) {
|
||||
if (value instanceof RubyFixnum) {
|
||||
RubyFixnum fixNum = (RubyFixnum) value;
|
||||
return (int) fixNum.getLongValue();
|
||||
} else {
|
||||
throw getRuntime().newArgumentError(paramName + " must be integer");
|
||||
}
|
||||
}
|
||||
|
||||
private int rubyFixnumToNonNegativeInt(IRubyObject value, String paramName) {
|
||||
if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() >= 0) {
|
||||
RubyFixnum fixNum = (RubyFixnum) value;
|
||||
return (int) fixNum.getLongValue();
|
||||
} else {
|
||||
throw getRuntime().newArgumentError(paramName + " must be a non-negative integer");
|
||||
}
|
||||
}
|
||||
|
||||
private int rubyFixnumToPositiveInt(IRubyObject value, String paramName) {
|
||||
if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() > 0) {
|
||||
RubyFixnum fixNum = (RubyFixnum) value;
|
||||
return (int) fixNum.getLongValue();
|
||||
} else {
|
||||
throw getRuntime().newArgumentError(paramName + " must be an integer greater than zero");
|
||||
}
|
||||
}
|
||||
|
||||
private long rubyNumericToLong(IRubyObject value, String paramName) {
|
||||
if (value instanceof RubyNumeric && ((RubyNumeric) value).getDoubleValue() > 0) {
|
||||
RubyNumeric fixNum = (RubyNumeric) value;
|
||||
return fixNum.getLongValue();
|
||||
} else {
|
||||
throw getRuntime().newArgumentError(paramName + " must be a float greater than zero");
|
||||
}
|
||||
}
|
||||
|
||||
class JRubySemaphore extends Semaphore {
|
||||
|
||||
public JRubySemaphore(int permits) {
|
||||
super(permits);
|
||||
}
|
||||
|
||||
public JRubySemaphore(int permits, boolean value) {
|
||||
super(permits, value);
|
||||
}
|
||||
|
||||
public void publicReducePermits(int i) {
|
||||
reducePermits(i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
package com.concurrent_ruby.ext;
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyBasicObject;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.RubyObject;
|
||||
import org.jruby.RubyThread;
|
||||
import org.jruby.anno.JRubyClass;
|
||||
import org.jruby.anno.JRubyMethod;
|
||||
import org.jruby.runtime.Block;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.Visibility;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.Library;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class SynchronizationLibrary implements Library {
|
||||
|
||||
private static final Unsafe UNSAFE = loadUnsafe();
|
||||
private static final boolean FULL_FENCE = supportsFences();
|
||||
|
||||
private static Unsafe loadUnsafe() {
|
||||
try {
|
||||
Class ncdfe = Class.forName("sun.misc.Unsafe");
|
||||
Field f = ncdfe.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
return (Unsafe) f.get((java.lang.Object) null);
|
||||
} catch (Exception var2) {
|
||||
return null;
|
||||
} catch (NoClassDefFoundError var3) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean supportsFences() {
|
||||
if (UNSAFE == null) {
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
Method m = UNSAFE.getClass().getDeclaredMethod("fullFence", new Class[0]);
|
||||
if (m != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception var1) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final ObjectAllocator JRUBY_OBJECT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRubyObject(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static final ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new Object(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static final ObjectAllocator ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new AbstractLockableObject(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static final ObjectAllocator JRUBY_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRubyLockableObject(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
public void load(Ruby runtime, boolean wrap) throws IOException {
|
||||
RubyModule synchronizationModule = runtime.
|
||||
defineModule("Concurrent").
|
||||
defineModuleUnder("Synchronization");
|
||||
|
||||
RubyModule jrubyAttrVolatileModule = synchronizationModule.defineModuleUnder("JRubyAttrVolatile");
|
||||
jrubyAttrVolatileModule.defineAnnotatedMethods(JRubyAttrVolatile.class);
|
||||
|
||||
defineClass(runtime, synchronizationModule, "AbstractObject", "JRubyObject",
|
||||
JRubyObject.class, JRUBY_OBJECT_ALLOCATOR);
|
||||
|
||||
defineClass(runtime, synchronizationModule, "JRubyObject", "Object",
|
||||
Object.class, OBJECT_ALLOCATOR);
|
||||
|
||||
defineClass(runtime, synchronizationModule, "Object", "AbstractLockableObject",
|
||||
AbstractLockableObject.class, ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR);
|
||||
|
||||
defineClass(runtime, synchronizationModule, "AbstractLockableObject", "JRubyLockableObject",
|
||||
JRubyLockableObject.class, JRUBY_LOCKABLE_OBJECT_ALLOCATOR);
|
||||
|
||||
defineClass(runtime, synchronizationModule, "Object", "JRuby",
|
||||
JRuby.class, new ObjectAllocator() {
|
||||
@Override
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new JRuby(runtime, klazz);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private RubyClass defineClass(
|
||||
Ruby runtime,
|
||||
RubyModule namespace,
|
||||
String parentName,
|
||||
String name,
|
||||
Class javaImplementation,
|
||||
ObjectAllocator allocator) {
|
||||
final RubyClass parentClass = namespace.getClass(parentName);
|
||||
|
||||
if (parentClass == null) {
|
||||
System.out.println("not found " + parentName);
|
||||
throw runtime.newRuntimeError(namespace.toString() + "::" + parentName + " is missing");
|
||||
}
|
||||
|
||||
final RubyClass newClass = namespace.defineClassUnder(name, parentClass, allocator);
|
||||
newClass.defineAnnotatedMethods(javaImplementation);
|
||||
return newClass;
|
||||
}
|
||||
|
||||
// Facts:
|
||||
// - all ivar reads are without any synchronisation of fences see
|
||||
// https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/VariableAccessor.java#L110-110
|
||||
// - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor
|
||||
// SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or
|
||||
// volatilePut
|
||||
// TODO (pitr 16-Sep-2015): what do we do in Java 9 ?
|
||||
|
||||
// module JRubyAttrVolatile
|
||||
public static class JRubyAttrVolatile {
|
||||
|
||||
// volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic
|
||||
// on volatile fields. any volatile field could have been used but using the thread context is an
|
||||
// attempt to avoid code elimination.
|
||||
private static volatile int volatileField;
|
||||
|
||||
@JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC)
|
||||
public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject self) {
|
||||
// Prevent reordering of ivar writes with publication of this instance
|
||||
if (!FULL_FENCE) {
|
||||
// Assuming that following volatile read and write is not eliminated it simulates fullFence.
|
||||
// If it's eliminated it'll cause problems only on non-x86 platforms.
|
||||
// http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding
|
||||
final int volatileRead = volatileField;
|
||||
volatileField = context.getLine();
|
||||
} else {
|
||||
UNSAFE.fullFence();
|
||||
}
|
||||
return context.nil;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC)
|
||||
public static IRubyObject instanceVariableGetVolatile(
|
||||
ThreadContext context,
|
||||
IRubyObject self,
|
||||
IRubyObject name) {
|
||||
// Ensure we ses latest value with loadFence
|
||||
if (!FULL_FENCE) {
|
||||
// piggybacking on volatile read, simulating loadFence
|
||||
final int volatileRead = volatileField;
|
||||
return ((RubyBasicObject) self).instance_variable_get(context, name);
|
||||
} else {
|
||||
UNSAFE.loadFence();
|
||||
return ((RubyBasicObject) self).instance_variable_get(context, name);
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC)
|
||||
public static IRubyObject InstanceVariableSetVolatile(
|
||||
ThreadContext context,
|
||||
IRubyObject self,
|
||||
IRubyObject name,
|
||||
IRubyObject value) {
|
||||
// Ensure we make last update visible
|
||||
if (!FULL_FENCE) {
|
||||
// piggybacking on volatile write, simulating storeFence
|
||||
final IRubyObject result = ((RubyBasicObject) self).instance_variable_set(name, value);
|
||||
volatileField = context.getLine();
|
||||
return result;
|
||||
} else {
|
||||
// JRuby uses StampedVariableAccessor which calls fullFence
|
||||
// so no additional steps needed.
|
||||
// See https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/StampedVariableAccessor.java#L151-L159
|
||||
return ((RubyBasicObject) self).instance_variable_set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyClass(name = "JRubyObject", parent = "AbstractObject")
|
||||
public static class JRubyObject extends RubyObject {
|
||||
|
||||
public JRubyObject(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyClass(name = "Object", parent = "JRubyObject")
|
||||
public static class Object extends JRubyObject {
|
||||
|
||||
public Object(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyClass(name = "AbstractLockableObject", parent = "Object")
|
||||
public static class AbstractLockableObject extends Object {
|
||||
|
||||
public AbstractLockableObject(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyClass(name = "JRubyLockableObject", parent = "AbstractLockableObject")
|
||||
public static class JRubyLockableObject extends JRubyObject {
|
||||
|
||||
public JRubyLockableObject(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "synchronize", visibility = Visibility.PROTECTED)
|
||||
public IRubyObject rubySynchronize(ThreadContext context, Block block) {
|
||||
synchronized (this) {
|
||||
return block.yield(context, null);
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "ns_wait", optional = 1, visibility = Visibility.PROTECTED)
|
||||
public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) {
|
||||
Ruby runtime = context.runtime;
|
||||
if (args.length > 1) {
|
||||
throw runtime.newArgumentError(args.length, 1);
|
||||
}
|
||||
Double timeout = null;
|
||||
if (args.length > 0 && !args[0].isNil()) {
|
||||
timeout = args[0].convertToFloat().getDoubleValue();
|
||||
if (timeout < 0) {
|
||||
throw runtime.newArgumentError("time interval must be positive");
|
||||
}
|
||||
}
|
||||
if (Thread.interrupted()) {
|
||||
throw runtime.newConcurrencyError("thread interrupted");
|
||||
}
|
||||
boolean success = false;
|
||||
try {
|
||||
success = context.getThread().wait_timeout(this, timeout);
|
||||
} catch (InterruptedException ie) {
|
||||
throw runtime.newConcurrencyError(ie.getLocalizedMessage());
|
||||
} finally {
|
||||
// An interrupt or timeout may have caused us to miss
|
||||
// a notify that we consumed, so do another notify in
|
||||
// case someone else is available to pick it up.
|
||||
if (!success) {
|
||||
this.notify();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "ns_signal", visibility = Visibility.PROTECTED)
|
||||
public IRubyObject nsSignal(ThreadContext context) {
|
||||
notify();
|
||||
return this;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "ns_broadcast", visibility = Visibility.PROTECTED)
|
||||
public IRubyObject nsBroadcast(ThreadContext context) {
|
||||
notifyAll();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@JRubyClass(name = "JRuby")
|
||||
public static class JRuby extends RubyObject {
|
||||
public JRuby(Ruby runtime, RubyClass metaClass) {
|
||||
super(runtime, metaClass);
|
||||
}
|
||||
|
||||
@JRubyMethod(name = "sleep_interruptibly", visibility = Visibility.PUBLIC, module = true)
|
||||
public static IRubyObject sleepInterruptibly(final ThreadContext context, IRubyObject receiver, final Block block) {
|
||||
try {
|
||||
context.getThread().executeBlockingTask(new RubyThread.BlockingTask() {
|
||||
@Override
|
||||
public void run() throws InterruptedException {
|
||||
block.call(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wakeup() {
|
||||
context.getThread().getNativeThread().interrupt();
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
throw context.runtime.newThreadError("interrupted in Concurrent::Synchronization::JRuby.sleep_interruptibly");
|
||||
}
|
||||
return context.nil;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.concurrent_ruby.ext.jsr166e;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ConcurrentHashMap<K, V> {
|
||||
/** Interface describing a function of one argument */
|
||||
public interface Fun<A,T> { T apply(A a); }
|
||||
/** Interface describing a function of two arguments */
|
||||
public interface BiFun<A,B,T> { T apply(A a, B b); }
|
||||
|
||||
public V get(K key);
|
||||
public V put(K key, V value);
|
||||
public V putIfAbsent(K key, V value);
|
||||
public V computeIfAbsent(K key, Fun<? super K, ? extends V> mf);
|
||||
public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> mf);
|
||||
public V compute(K key, BiFun<? super K, ? super V, ? extends V> mf);
|
||||
public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> mf);
|
||||
public boolean replace(K key, V oldVal, V newVal);
|
||||
public V replace(K key, V value);
|
||||
public boolean containsKey(K key);
|
||||
public boolean remove(Object key, Object value);
|
||||
public V remove(K key);
|
||||
public void clear();
|
||||
public Set<Map.Entry<K,V>> entrySet();
|
||||
public int size();
|
||||
public V getValueOrDefault(Object key, V defaultValue);
|
||||
|
||||
public boolean containsValue(V value);
|
||||
public K findKey(V value);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
||||
* Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This is based on 1.9 version.
|
||||
|
||||
package com.concurrent_ruby.ext.jsr166e;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* One or more variables that together maintain an initially zero
|
||||
* {@code long} sum. When updates (method {@link #add}) are contended
|
||||
* across threads, the set of variables may grow dynamically to reduce
|
||||
* contention. Method {@link #sum} (or, equivalently, {@link
|
||||
* #longValue}) returns the current total combined across the
|
||||
* variables maintaining the sum.
|
||||
*
|
||||
* <p>This class is usually preferable to {@link AtomicLong} when
|
||||
* multiple threads update a common sum that is used for purposes such
|
||||
* as collecting statistics, not for fine-grained synchronization
|
||||
* control. Under low update contention, the two classes have similar
|
||||
* characteristics. But under high contention, expected throughput of
|
||||
* this class is significantly higher, at the expense of higher space
|
||||
* consumption.
|
||||
*
|
||||
* <p>This class extends {@link Number}, but does <em>not</em> define
|
||||
* methods such as {@code hashCode} and {@code compareTo} because
|
||||
* instances are expected to be mutated, and so are not useful as
|
||||
* collection keys.
|
||||
*
|
||||
* <p><em>jsr166e note: This class is targeted to be placed in
|
||||
* java.util.concurrent.atomic.</em>
|
||||
*
|
||||
* @since 1.8
|
||||
* @author Doug Lea
|
||||
*/
|
||||
public class LongAdder extends Striped64 implements Serializable {
|
||||
private static final long serialVersionUID = 7249069246863182397L;
|
||||
|
||||
/**
|
||||
* Version of plus for use in retryUpdate
|
||||
*/
|
||||
final long fn(long v, long x) { return v + x; }
|
||||
|
||||
/**
|
||||
* Creates a new adder with initial sum of zero.
|
||||
*/
|
||||
public LongAdder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given value.
|
||||
*
|
||||
* @param x the value to add
|
||||
*/
|
||||
public void add(long x) {
|
||||
Cell[] as; long b, v; HashCode hc; Cell a; int n;
|
||||
if ((as = cells) != null || !casBase(b = base, b + x)) {
|
||||
boolean uncontended = true;
|
||||
int h = (hc = threadHashCode.get()).code;
|
||||
if (as == null || (n = as.length) < 1 ||
|
||||
(a = as[(n - 1) & h]) == null ||
|
||||
!(uncontended = a.cas(v = a.value, v + x)))
|
||||
retryUpdate(x, hc, uncontended);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@code add(1)}.
|
||||
*/
|
||||
public void increment() {
|
||||
add(1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@code add(-1)}.
|
||||
*/
|
||||
public void decrement() {
|
||||
add(-1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current sum. The returned value is <em>NOT</em> an
|
||||
* atomic snapshot: Invocation in the absence of concurrent
|
||||
* updates returns an accurate result, but concurrent updates that
|
||||
* occur while the sum is being calculated might not be
|
||||
* incorporated.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long sum() {
|
||||
long sum = base;
|
||||
Cell[] as = cells;
|
||||
if (as != null) {
|
||||
int n = as.length;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Cell a = as[i];
|
||||
if (a != null)
|
||||
sum += a.value;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets variables maintaining the sum to zero. This method may
|
||||
* be a useful alternative to creating a new adder, but is only
|
||||
* effective if there are no concurrent updates. Because this
|
||||
* method is intrinsically racy, it should only be used when it is
|
||||
* known that no threads are concurrently updating.
|
||||
*/
|
||||
public void reset() {
|
||||
internalReset(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent in effect to {@link #sum} followed by {@link
|
||||
* #reset}. This method may apply for example during quiescent
|
||||
* points between multithreaded computations. If there are
|
||||
* updates concurrent with this method, the returned value is
|
||||
* <em>not</em> guaranteed to be the final value occurring before
|
||||
* the reset.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long sumThenReset() {
|
||||
long sum = base;
|
||||
Cell[] as = cells;
|
||||
base = 0L;
|
||||
if (as != null) {
|
||||
int n = as.length;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Cell a = as[i];
|
||||
if (a != null) {
|
||||
sum += a.value;
|
||||
a.value = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the {@link #sum}.
|
||||
* @return the String representation of the {@link #sum}
|
||||
*/
|
||||
public String toString() {
|
||||
return Long.toString(sum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #sum}.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long longValue() {
|
||||
return sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as an {@code int} after a narrowing
|
||||
* primitive conversion.
|
||||
*/
|
||||
public int intValue() {
|
||||
return (int)sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as a {@code float}
|
||||
* after a widening primitive conversion.
|
||||
*/
|
||||
public float floatValue() {
|
||||
return (float)sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as a {@code double} after a widening
|
||||
* primitive conversion.
|
||||
*/
|
||||
public double doubleValue() {
|
||||
return (double)sum();
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
s.defaultWriteObject();
|
||||
s.writeLong(sum());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
busy = 0;
|
||||
cells = null;
|
||||
base = s.readLong();
|
||||
}
|
||||
|
||||
}
|
@ -1,342 +0,0 @@
|
||||
/*
|
||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
||||
* Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This is based on 1.5 version.
|
||||
|
||||
package com.concurrent_ruby.ext.jsr166e;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* A package-local class holding common representation and mechanics
|
||||
* for classes supporting dynamic striping on 64bit values. The class
|
||||
* extends Number so that concrete subclasses must publicly do so.
|
||||
*/
|
||||
abstract class Striped64 extends Number {
|
||||
/*
|
||||
* This class maintains a lazily-initialized table of atomically
|
||||
* updated variables, plus an extra "base" field. The table size
|
||||
* is a power of two. Indexing uses masked per-thread hash codes.
|
||||
* Nearly all declarations in this class are package-private,
|
||||
* accessed directly by subclasses.
|
||||
*
|
||||
* Table entries are of class Cell; a variant of AtomicLong padded
|
||||
* to reduce cache contention on most processors. Padding is
|
||||
* overkill for most Atomics because they are usually irregularly
|
||||
* scattered in memory and thus don't interfere much with each
|
||||
* other. But Atomic objects residing in arrays will tend to be
|
||||
* placed adjacent to each other, and so will most often share
|
||||
* cache lines (with a huge negative performance impact) without
|
||||
* this precaution.
|
||||
*
|
||||
* In part because Cells are relatively large, we avoid creating
|
||||
* them until they are needed. When there is no contention, all
|
||||
* updates are made to the base field. Upon first contention (a
|
||||
* failed CAS on base update), the table is initialized to size 2.
|
||||
* The table size is doubled upon further contention until
|
||||
* reaching the nearest power of two greater than or equal to the
|
||||
* number of CPUS. Table slots remain empty (null) until they are
|
||||
* needed.
|
||||
*
|
||||
* A single spinlock ("busy") is used for initializing and
|
||||
* resizing the table, as well as populating slots with new Cells.
|
||||
* There is no need for a blocking lock: When the lock is not
|
||||
* available, threads try other slots (or the base). During these
|
||||
* retries, there is increased contention and reduced locality,
|
||||
* which is still better than alternatives.
|
||||
*
|
||||
* Per-thread hash codes are initialized to random values.
|
||||
* Contention and/or table collisions are indicated by failed
|
||||
* CASes when performing an update operation (see method
|
||||
* retryUpdate). Upon a collision, if the table size is less than
|
||||
* the capacity, it is doubled in size unless some other thread
|
||||
* holds the lock. If a hashed slot is empty, and lock is
|
||||
* available, a new Cell is created. Otherwise, if the slot
|
||||
* exists, a CAS is tried. Retries proceed by "double hashing",
|
||||
* using a secondary hash (Marsaglia XorShift) to try to find a
|
||||
* free slot.
|
||||
*
|
||||
* The table size is capped because, when there are more threads
|
||||
* than CPUs, supposing that each thread were bound to a CPU,
|
||||
* there would exist a perfect hash function mapping threads to
|
||||
* slots that eliminates collisions. When we reach capacity, we
|
||||
* search for this mapping by randomly varying the hash codes of
|
||||
* colliding threads. Because search is random, and collisions
|
||||
* only become known via CAS failures, convergence can be slow,
|
||||
* and because threads are typically not bound to CPUS forever,
|
||||
* may not occur at all. However, despite these limitations,
|
||||
* observed contention rates are typically low in these cases.
|
||||
*
|
||||
* It is possible for a Cell to become unused when threads that
|
||||
* once hashed to it terminate, as well as in the case where
|
||||
* doubling the table causes no thread to hash to it under
|
||||
* expanded mask. We do not try to detect or remove such cells,
|
||||
* under the assumption that for long-running instances, observed
|
||||
* contention levels will recur, so the cells will eventually be
|
||||
* needed again; and for short-lived ones, it does not matter.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Padded variant of AtomicLong supporting only raw accesses plus CAS.
|
||||
* The value field is placed between pads, hoping that the JVM doesn't
|
||||
* reorder them.
|
||||
*
|
||||
* JVM intrinsics note: It would be possible to use a release-only
|
||||
* form of CAS here, if it were provided.
|
||||
*/
|
||||
static final class Cell {
|
||||
volatile long p0, p1, p2, p3, p4, p5, p6;
|
||||
volatile long value;
|
||||
volatile long q0, q1, q2, q3, q4, q5, q6;
|
||||
Cell(long x) { value = x; }
|
||||
|
||||
final boolean cas(long cmp, long val) {
|
||||
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
|
||||
}
|
||||
|
||||
// Unsafe mechanics
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
private static final long valueOffset;
|
||||
static {
|
||||
try {
|
||||
UNSAFE = getUnsafe();
|
||||
Class<?> ak = Cell.class;
|
||||
valueOffset = UNSAFE.objectFieldOffset
|
||||
(ak.getDeclaredField("value"));
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder for the thread-local hash code. The code is initially
|
||||
* random, but may be set to a different value upon collisions.
|
||||
*/
|
||||
static final class HashCode {
|
||||
static final Random rng = new Random();
|
||||
int code;
|
||||
HashCode() {
|
||||
int h = rng.nextInt(); // Avoid zero to allow xorShift rehash
|
||||
code = (h == 0) ? 1 : h;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The corresponding ThreadLocal class
|
||||
*/
|
||||
static final class ThreadHashCode extends ThreadLocal<HashCode> {
|
||||
public HashCode initialValue() { return new HashCode(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Static per-thread hash codes. Shared across all instances to
|
||||
* reduce ThreadLocal pollution and because adjustments due to
|
||||
* collisions in one table are likely to be appropriate for
|
||||
* others.
|
||||
*/
|
||||
static final ThreadHashCode threadHashCode = new ThreadHashCode();
|
||||
|
||||
/** Number of CPUS, to place bound on table size */
|
||||
static final int NCPU = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
/**
|
||||
* Table of cells. When non-null, size is a power of 2.
|
||||
*/
|
||||
transient volatile Cell[] cells;
|
||||
|
||||
/**
|
||||
* Base value, used mainly when there is no contention, but also as
|
||||
* a fallback during table initialization races. Updated via CAS.
|
||||
*/
|
||||
transient volatile long base;
|
||||
|
||||
/**
|
||||
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
|
||||
*/
|
||||
transient volatile int busy;
|
||||
|
||||
/**
|
||||
* Package-private default constructor
|
||||
*/
|
||||
Striped64() {
|
||||
}
|
||||
|
||||
/**
|
||||
* CASes the base field.
|
||||
*/
|
||||
final boolean casBase(long cmp, long val) {
|
||||
return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* CASes the busy field from 0 to 1 to acquire lock.
|
||||
*/
|
||||
final boolean casBusy() {
|
||||
return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the function of current and new value. Subclasses
|
||||
* should open-code this update function for most uses, but the
|
||||
* virtualized form is needed within retryUpdate.
|
||||
*
|
||||
* @param currentValue the current value (of either base or a cell)
|
||||
* @param newValue the argument from a user update call
|
||||
* @return result of the update function
|
||||
*/
|
||||
abstract long fn(long currentValue, long newValue);
|
||||
|
||||
/**
|
||||
* Handles cases of updates involving initialization, resizing,
|
||||
* creating new Cells, and/or contention. See above for
|
||||
* explanation. This method suffers the usual non-modularity
|
||||
* problems of optimistic retry code, relying on rechecked sets of
|
||||
* reads.
|
||||
*
|
||||
* @param x the value
|
||||
* @param hc the hash code holder
|
||||
* @param wasUncontended false if CAS failed before call
|
||||
*/
|
||||
final void retryUpdate(long x, HashCode hc, boolean wasUncontended) {
|
||||
int h = hc.code;
|
||||
boolean collide = false; // True if last slot nonempty
|
||||
for (;;) {
|
||||
Cell[] as; Cell a; int n; long v;
|
||||
if ((as = cells) != null && (n = as.length) > 0) {
|
||||
if ((a = as[(n - 1) & h]) == null) {
|
||||
if (busy == 0) { // Try to attach new Cell
|
||||
Cell r = new Cell(x); // Optimistically create
|
||||
if (busy == 0 && casBusy()) {
|
||||
boolean created = false;
|
||||
try { // Recheck under lock
|
||||
Cell[] rs; int m, j;
|
||||
if ((rs = cells) != null &&
|
||||
(m = rs.length) > 0 &&
|
||||
rs[j = (m - 1) & h] == null) {
|
||||
rs[j] = r;
|
||||
created = true;
|
||||
}
|
||||
} finally {
|
||||
busy = 0;
|
||||
}
|
||||
if (created)
|
||||
break;
|
||||
continue; // Slot is now non-empty
|
||||
}
|
||||
}
|
||||
collide = false;
|
||||
}
|
||||
else if (!wasUncontended) // CAS already known to fail
|
||||
wasUncontended = true; // Continue after rehash
|
||||
else if (a.cas(v = a.value, fn(v, x)))
|
||||
break;
|
||||
else if (n >= NCPU || cells != as)
|
||||
collide = false; // At max size or stale
|
||||
else if (!collide)
|
||||
collide = true;
|
||||
else if (busy == 0 && casBusy()) {
|
||||
try {
|
||||
if (cells == as) { // Expand table unless stale
|
||||
Cell[] rs = new Cell[n << 1];
|
||||
for (int i = 0; i < n; ++i)
|
||||
rs[i] = as[i];
|
||||
cells = rs;
|
||||
}
|
||||
} finally {
|
||||
busy = 0;
|
||||
}
|
||||
collide = false;
|
||||
continue; // Retry with expanded table
|
||||
}
|
||||
h ^= h << 13; // Rehash
|
||||
h ^= h >>> 17;
|
||||
h ^= h << 5;
|
||||
}
|
||||
else if (busy == 0 && cells == as && casBusy()) {
|
||||
boolean init = false;
|
||||
try { // Initialize table
|
||||
if (cells == as) {
|
||||
Cell[] rs = new Cell[2];
|
||||
rs[h & 1] = new Cell(x);
|
||||
cells = rs;
|
||||
init = true;
|
||||
}
|
||||
} finally {
|
||||
busy = 0;
|
||||
}
|
||||
if (init)
|
||||
break;
|
||||
}
|
||||
else if (casBase(v = base, fn(v, x)))
|
||||
break; // Fall back on using base
|
||||
}
|
||||
hc.code = h; // Record index for next time
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets base and all cells to the given value.
|
||||
*/
|
||||
final void internalReset(long initialValue) {
|
||||
Cell[] as = cells;
|
||||
base = initialValue;
|
||||
if (as != null) {
|
||||
int n = as.length;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Cell a = as[i];
|
||||
if (a != null)
|
||||
a.value = initialValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unsafe mechanics
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
private static final long baseOffset;
|
||||
private static final long busyOffset;
|
||||
static {
|
||||
try {
|
||||
UNSAFE = getUnsafe();
|
||||
Class<?> sk = Striped64.class;
|
||||
baseOffset = UNSAFE.objectFieldOffset
|
||||
(sk.getDeclaredField("base"));
|
||||
busyOffset = UNSAFE.objectFieldOffset
|
||||
(sk.getDeclaredField("busy"));
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
|
||||
* Replace with a simple call to Unsafe.getUnsafe when integrating
|
||||
* into a jdk.
|
||||
*
|
||||
* @return a sun.misc.Unsafe
|
||||
*/
|
||||
private static sun.misc.Unsafe getUnsafe() {
|
||||
try {
|
||||
return sun.misc.Unsafe.getUnsafe();
|
||||
} catch (SecurityException se) {
|
||||
try {
|
||||
return java.security.AccessController.doPrivileged
|
||||
(new java.security
|
||||
.PrivilegedExceptionAction<sun.misc.Unsafe>() {
|
||||
public sun.misc.Unsafe run() throws Exception {
|
||||
java.lang.reflect.Field f = sun.misc
|
||||
.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
return (sun.misc.Unsafe) f.get(null);
|
||||
}});
|
||||
} catch (java.security.PrivilegedActionException e) {
|
||||
throw new RuntimeException("Could not initialize intrinsics",
|
||||
e.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user